]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- adjustments to eager loading so that its "eager chain" is
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 21 Sep 2006 20:26:33 +0000 (20:26 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 21 Sep 2006 20:26:33 +0000 (20:26 +0000)
kept separate from the normal mapper setup, thereby
preventing conflicts with lazy loader operation, fixes
[ticket:308]

CHANGES
lib/sqlalchemy/orm/mapper.py
lib/sqlalchemy/orm/properties.py

diff --git a/CHANGES b/CHANGES
index ddba5ec21562afb8f1252385b52971c6ed6b8b59..decfaafed51096730f606a80ea37172658a862de 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -26,6 +26,10 @@ updating too many rows, updates only required columns
 the appropriate negation operator if one is available.
 - calling a negation on an "IN" or "IS" clause will result in
 "NOT IN", "IS NOT" (as opposed to NOT (x IN y)). 
+- adjustments to eager loading so that its "eager chain" is
+kept separate from the normal mapper setup, thereby
+preventing conflicts with lazy loader operation, fixes 
+[ticket:308]
 
 0.2.8
 - cleanup on connection methods + documentation.  custom DBAPI
index 194b2b9e6fd589d35e159f30b77c77d40dc22a21..f8df559022b3a704dc21c24232a453accccf8473 100644 (file)
@@ -566,7 +566,7 @@ class Mapper(object):
             prop.adapt_to_inherited(key, mapper)
         
     def __str__(self):
-        return "Mapper|" + self.class_.__name__ + "|" + (self.entity_name is not None and "/%s" % self.entity_name or "") + str(self.local_table)
+        return "Mapper| " + str(id(self)) + "|" + self.class_.__name__ + "|" + (self.entity_name is not None and "/%s" % self.entity_name or "") + (self.local_table and self.local_table.name or str(self.local_table)) + "|is_primary=" + repr(self._is_primary_mapper())
     
     def _is_primary_mapper(self):
         """returns True if this mapper is the primary mapper for its class key (class + entity_name)"""
index 8372c41f85a8bdc025b19cf42dfb31c85672c1fb..23398f8fef79a9c0183295fa57c65f4c50b99922 100644 (file)
@@ -161,6 +161,8 @@ class PropertyLoader(mapper.MapperProperty):
         
     private = property(lambda s:s.cascade.delete_orphan)
 
+    def __str__(self):
+        return self.__class__.__name__ + " " + str(self.parent) + "->" + self.key + "->" + str(self.mapper)
     def cascade_iterator(self, type, object, recursive):
         if not type in self.cascade:
             return
@@ -373,6 +375,7 @@ class LazyLoader(PropertyLoader):
         self._register_attribute(class_, callable_=lambda i: self.setup_loader(i))
 
     def setup_loader(self, instance):
+        #print self, "setup_loader", "parent", self.parent.mapped_table, "child", self.mapper.mapped_table, "join", self.lazywhere
         # make sure our parent mapper is the one thats assigned to this instance, else call that one
         if not self.localparent.is_assigned(instance):
             # if no mapper association with this instance (i.e. not in a session, not loaded by a mapper),
@@ -533,15 +536,15 @@ class EagerLoader(LazyLoader):
 
         if len(eagerprops):
             recursion_stack[self.localparent.mapped_table] = True
-            self.mapper = self.mapper.copy()
+            self.eagermapper = self.mapper.copy()
             try:
                 for prop in eagerprops:
                     if recursion_stack.has_key(prop.target):
                         # recursion - set the relationship as a LazyLoader
-                        p = EagerLazyOption(None, False).create_prop(self.mapper, prop.key)
+                        p = EagerLazyOption(None, False).create_prop(self.eagermapper, prop.key)
                         continue
                     p = prop.copy()
-                    self.mapper.props[prop.key] = p
+                    self.eagermapper.props[prop.key] = p
 #                    print "we are:", id(self), self.target.name, (self.secondary and self.secondary.name or "None"), self.parent.mapped_table.name
 #                    print "prop is",id(prop), prop.target.name, (prop.secondary and prop.secondary.name or "None"), prop.parent.mapped_table.name
                     p.do_init_subclass(recursion_stack)
@@ -552,7 +555,8 @@ class EagerLoader(LazyLoader):
                     #print "new eagertqarget", p.eagertarget.name, (p.secondary and p.secondary.name or "none"), p.parent.mapped_table.name
             finally:
                 del recursion_stack[self.localparent.mapped_table]
-
+        else:
+            self.eagermapper = self.mapper
         self._row_decorator = self._create_decorator_row()
         self.__eager_chain_init = id(self)
         
@@ -597,7 +601,7 @@ class EagerLoader(LazyLoader):
             self._aliasize_orderby(statement.order_by_clause, False)
                 
         statement.append_from(statement._outerjoin)
-        for key, value in self.mapper.props.iteritems():
+        for key, value in self.eagermapper.props.iteritems():
             value.setup(key, statement, eagertable=self.eagertarget)
             
         
@@ -608,7 +612,7 @@ class EagerLoader(LazyLoader):
         decorated_row = self._decorate_row(row)
         try:
             # check for identity key
-            identity_key = self.mapper._row_identity_key(decorated_row)
+            identity_key = self.eagermapper._row_identity_key(decorated_row)
         except KeyError:
             # else degrade to a lazy loader
             LazyLoader.execute(self, session, instance, row, identitykey, imap, isnew)
@@ -619,11 +623,11 @@ class EagerLoader(LazyLoader):
             if isnew:
                 # set a scalar object instance directly on the parent object, 
                 # bypassing SmartProperty event handlers.
-                instance.__dict__[self.key] = self.mapper._instance(session, decorated_row, imap, None)
+                instance.__dict__[self.key] = self.eagermapper._instance(session, decorated_row, imap, None)
             else:
                 # call _instance on the row, even though the object has been created,
                 # so that we further descend into properties
-                self.mapper._instance(session, decorated_row, imap, None)
+                self.eagermapper._instance(session, decorated_row, imap, None)
         else:
             if isnew:
                 # call the SmartProperty's initialize() method to create a new, blank list
@@ -635,7 +639,7 @@ class EagerLoader(LazyLoader):
                 # store it in the "scratch" area, which is local to this load operation.
                 imap['_scratch'][(instance, self.key)] = appender
             result_list = imap['_scratch'][(instance, self.key)]
-            self.mapper._instance(session, decorated_row, imap, result_list)
+            self.eagermapper._instance(session, decorated_row, imap, result_list)
 
     def _create_decorator_row(self):
         class DecoratorDict(object):