From bba54e320df55d50f55715805498dc3ce8584991 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 30 Oct 2008 14:40:10 +0000 Subject: [PATCH] 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. --- lib/sqlalchemy/orm/strategies.py | 3 ++- test/orm/session.py | 15 +++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 3c156b70f2..1962a7e2d9 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -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) diff --git a/test/orm/session.py b/test/orm/session.py index eecb13d07f..58c4888a76 100644 --- a/test/orm/session.py +++ b/test/orm/session.py @@ -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 -- 2.47.3