]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
got some support for mapping to a select that only selects some of the columns of...
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 25 Mar 2006 02:25:59 +0000 (02:25 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 25 Mar 2006 02:25:59 +0000 (02:25 +0000)
examples/polymorph/polymorph2.py
lib/sqlalchemy/mapping/mapper.py
lib/sqlalchemy/mapping/unitofwork.py

index 99ee6c34c9d346d75426525a9e1c2e4451cf7448..eebac80c1812d22739ad2ce6b6a71fa134233b76 100644 (file)
@@ -94,8 +94,6 @@ class PersonLoader(MapperExtension):
             return False
         else:
             return True
-            
-        
 
 people_mapper = mapper(Person, person_join, extension=PersonLoader())
 
index 5b56358bae7830c44263a4ca8a0499640794fdbf..907d412faae5480f67c7c3624dac342506848769 100644 (file)
@@ -18,6 +18,11 @@ import weakref
 # a dictionary mapping classes to their primary mappers
 mapper_registry = weakref.WeakKeyDictionary()
 
+# a constant returned by _getattrbycolumn to indicate
+# this mapper is not handling an attribute for a particular
+# column
+NO_ATTRIBUTE = object()
+
 class Mapper(object):
     """Persists object instances to and from schema.Table objects via the sql package.
     Instances of this class should be constructed through this package's mapper() or
@@ -534,19 +539,25 @@ class Mapper(object):
             params = {}
         return self.instances(statement.execute(**params), **kwargs)
 
-    def _getpropbycolumn(self, column):
+    def _getpropbycolumn(self, column, raiseerror=True):
         try:
             prop = self.columntoproperty[column.original]
         except KeyError:
             try:
                 prop = self.props[column.key]
+                if not raiseerror:
+                    return None
                 raise InvalidRequestError("Column '%s.%s' is not available, due to conflicting property '%s':%s" % (column.table.name, column.name, column.key, repr(prop)))
             except KeyError:
+                if not raiseerror:
+                    return None
                 raise InvalidRequestError("No column %s.%s is configured on mapper %s..." % (column.table.name, column.name, str(self)))
         return prop[0]
         
-    def _getattrbycolumn(self, obj, column):
-        prop = self._getpropbycolumn(column)
+    def _getattrbycolumn(self, obj, column, raiseerror=True):
+        prop = self._getpropbycolumn(column, raiseerror)
+        if prop is None:
+            return NO_ATTRIBUTE
         return prop.getattr(obj)
 
     def _setattrbycolumn(self, obj, column, value):
@@ -615,7 +626,9 @@ class Mapper(object):
                             # doing an UPDATE ? get the history for the attribute, with "passive"
                             # so as not to trigger any deferred loads.  if there is a new
                             # value, add it to the bind parameters
-                            prop = self._getpropbycolumn(col)
+                            prop = self._getpropbycolumn(col, False)
+                            if prop is None:
+                                continue
                             history = prop.get_history(obj, passive=True)
                             if history:
                                 a = history.added_items()
@@ -629,7 +642,9 @@ class Mapper(object):
                             # default.  if its None and theres no default, we still might
                             # not want to put it in the col list but SQLIte doesnt seem to like that
                             # if theres no columns at all
-                            value = self._getattrbycolumn(obj, col)
+                            value = self._getattrbycolumn(obj, col, False)
+                            if value is NO_ATTRIBUTE:
+                                continue
                             if col.default is None or value is not None:
                                 params[col.key] = value
 
@@ -682,13 +697,16 @@ class Mapper(object):
                 clause.clauses.append(p == self._getattrbycolumn(obj, p))
             row = table.select(clause).execute().fetchone()
             for c in table.c:
-                if self._getattrbycolumn(obj, c) is None:
+                if self._getattrbycolumn(obj, c, False) is None:
                     self._setattrbycolumn(obj, c, row[c])
         else:
             for c in table.c:
                 if c.primary_key or not params.has_key(c.name):
                     continue
-                if self._getattrbycolumn(obj, c) != params.get_original(c.name):
+                v = self._getattrbycolumn(obj, c, False)
+                if v is NO_ATTRIBUTE:
+                    continue
+                elif v != params.get_original(c.name):
                     self._setattrbycolumn(obj, c, params.get_original(c.name))
 
     def delete_obj(self, objects, uow):
index 1e5388933d53ecbcfc65fc5eedbe647a3bcb92b4..fc589f65bbdfdc6867d2efef47c8868585c1b2b2 100644 (file)
@@ -737,7 +737,7 @@ class UOWTask(object):
         def _repr_task(task):
             if task.mapper is not None:
                 if task.mapper.__class__.__name__ == 'Mapper':
-                    name = task.mapper.class_.__name__ + "/" + task.mapper.primarytable.id + "/" + str(id(task.mapper))
+                    name = task.mapper.class_.__name__ + "/" + str(task.mapper.primarytable) + "/" + str(id(task.mapper))
                 else:
                     name = repr(task.mapper)
             else: