diff options
author | Mark Hahnenberg <mark@nylas.com> | 2016-07-12 10:23:58 -0700 |
---|---|---|
committer | Mark Hahnenberg <mark@nylas.com> | 2016-07-12 10:23:58 -0700 |
commit | d91084a3dcb0b770b6b0bb884d4a3f2e55770f60 (patch) | |
tree | 56382edd55814968e6a0b2a5c5e07154fd731c37 | |
parent | 2045689ff27708292d8effa782777ec55a8477d0 (diff) | |
download | sqlalchemy-pr/290.tar.gz |
Fix issue with unbaking subqueriespr/290
We were improperly capturing a loop variable inside a lambda during unbaking,
which would cause us to load incorrect data when executing queries.
-rw-r--r-- | lib/sqlalchemy/ext/baked.py | 3 | ||||
-rw-r--r-- | test/ext/test_baked.py | 33 |
2 files changed, 23 insertions, 13 deletions
diff --git a/lib/sqlalchemy/ext/baked.py b/lib/sqlalchemy/ext/baked.py index bfdc1e1a0..3ca94925e 100644 --- a/lib/sqlalchemy/ext/baked.py +++ b/lib/sqlalchemy/ext/baked.py @@ -194,7 +194,8 @@ class BakedQuery(object): """ for k, cache_key, query in context.attributes["baked_queries"]: - bk = BakedQuery(self._bakery, lambda sess: query.with_session(sess)) + bk = BakedQuery(self._bakery, + lambda sess, q=query: q.with_session(sess)) bk._cache_key = cache_key context.attributes[k] = bk.for_session(session).params(**params) diff --git a/test/ext/test_baked.py b/test/ext/test_baked.py index 8bfa58403..4250e363b 100644 --- a/test/ext/test_baked.py +++ b/test/ext/test_baked.py @@ -305,12 +305,16 @@ class ResultTest(BakedTest): def setup_mappers(cls): User = cls.classes.User Address = cls.classes.Address + Order = cls.classes.Order mapper(User, cls.tables.users, properties={ "addresses": relationship( - Address, order_by=cls.tables.addresses.c.id) + Address, order_by=cls.tables.addresses.c.id), + "orders": relationship( + Order, order_by=cls.tables.orders.c.id) }) mapper(Address, cls.tables.addresses) + mapper(Order, cls.tables.orders) def test_cachekeys_on_constructor(self): User = self.classes.User @@ -551,24 +555,29 @@ class ResultTest(BakedTest): def test_subquery_eagerloading(self): User = self.classes.User Address = self.classes.Address + Order = self.classes.Order - base_bq = self.bakery( - lambda s: s.query(User)) + # Override the default bakery for one with a smaller size. This used to + # trigger a bug when unbaking subqueries. + self.bakery = baked.bakery(size=3) + base_bq = self.bakery(lambda s: s.query(User)) - base_bq += lambda q: q.options(subqueryload(User.addresses)) + base_bq += lambda q: q.options(subqueryload(User.addresses), + subqueryload(User.orders)) base_bq += lambda q: q.order_by(User.id) assert_result = [ - User(id=7, addresses=[ - Address(id=1, email_address='jack@bean.com')]), + User(id=7, + addresses=[Address(id=1, email_address='jack@bean.com')], + orders=[Order(id=1), Order(id=3), Order(id=5)]), User(id=8, addresses=[ Address(id=2, email_address='ed@wood.com'), Address(id=3, email_address='ed@bettyboop.com'), Address(id=4, email_address='ed@lala.com'), ]), - User(id=9, addresses=[ - Address(id=5) - ]), + User(id=9, + addresses=[Address(id=5)], + orders=[Order(id=2), Order(id=4)]), User(id=10, addresses=[]) ] @@ -603,18 +612,18 @@ class ResultTest(BakedTest): def go(): result = bq(sess).all() eq_(assert_result[1:2], result) - self.assert_sql_count(testing.db, go, 2) + self.assert_sql_count(testing.db, go, 3) else: if cond1: def go(): result = bq(sess).all() eq_(assert_result[0:1], result) - self.assert_sql_count(testing.db, go, 2) + self.assert_sql_count(testing.db, go, 3) else: def go(): result = bq(sess).all() eq_(assert_result[1:3], result) - self.assert_sql_count(testing.db, go, 2) + self.assert_sql_count(testing.db, go, 3) sess.close() |