Commits

Mike Bayer committed 66788b1

the recent change to garbage collection of InstanceState meant that
the deferred lambda: created by lazy_clause would get a state with
no dict. creates strong reference to the object now.

  • Participants
  • Parent commits 1e3486d

Comments (0)

Files changed (2)

lib/sqlalchemy/orm/strategies.py

                 # 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)

test/orm/session.py

 
     @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)
         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