]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
the recent change to garbage collection of InstanceState meant that
authorMike Bayer <mike_mp@zzzcomputing.com>
Thu, 30 Oct 2008 14:40:10 +0000 (14:40 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Thu, 30 Oct 2008 14:40:10 +0000 (14:40 +0000)
the deferred lambda: created by lazy_clause would get a state with
no dict.  creates strong reference to the object now.

lib/sqlalchemy/orm/strategies.py
test/orm/session.py

index 3c156b70f24f6f7fed6df7405ff87262d60fc2e2..1962a7e2d9c55968744c7c3c88b92a15318bd304 100644 (file)
@@ -368,7 +368,8 @@ class LazyLoader(AbstractRelationLoader):
                 # use the "committed" (database) version to get query column values
                 # also its a deferred value; so that when used by Query, the committed value is used
                 # after an autoflush occurs
-                bindparam.value = lambda: mapper._get_committed_state_attr_by_column(state, bind_to_col[bindparam.key])
+                o = state.obj() # strong ref
+                bindparam.value = lambda: mapper._get_committed_attr_by_column(o, bind_to_col[bindparam.key])
 
         if self.parent_property.secondary and alias_secondary:
             criterion = sql_util.ClauseAdapter(self.parent_property.secondary.alias()).traverse(criterion)
index eecb13d07f9319e5d5181db709c8f8a3ff5ba69c..58c4888a761aca2be1aa329c254e61139e9a7745 100644 (file)
@@ -207,6 +207,11 @@ class SessionTest(_fixtures.FixtureTest):
 
     @testing.resolve_artifact_names
     def test_autoflush_expressions(self):
+        """test that an expression which is dependent on object state is 
+        evaluated after the session autoflushes.   This is the lambda
+        inside of strategies.py lazy_clause.
+        
+        """
         mapper(User, users, properties={
             'addresses':relation(Address, backref="user")})
         mapper(Address, addresses)
@@ -217,6 +222,16 @@ class SessionTest(_fixtures.FixtureTest):
         eq_(sess.query(Address).filter(Address.user==u).one(),
             Address(email_address='foo'))
 
+        # still works after "u" is garbage collected
+        sess.commit()
+        sess.close()
+        u = sess.query(User).get(u.id)
+        q = sess.query(Address).filter(Address.user==u)
+        del u
+        gc.collect()
+        eq_(q.one(), Address(email_address='foo'))
+
+
     @testing.crashes('mssql', 'test causes mssql to hang')
     @testing.requires.independent_connections
     @engines.close_open_connections