diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-10-04 22:39:19 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-10-04 22:39:19 +0000 |
commit | a9a4da62cfe4a7dbe6afff1f993e161e8243a6dc (patch) | |
tree | 9e98a22be2db887741208afe1176698e56f62d02 /test/orm/query.py | |
parent | f4871697774a512bebf0dd11866d3b0e8eb54b91 (diff) | |
download | sqlalchemy-a9a4da62cfe4a7dbe6afff1f993e161e8243a6dc.tar.gz |
- using contains_eager() against an alias combined with an overall query alias repaired - the
contains_eager adapter wraps the query adapter, not vice versa. Test coverage added.
- contains_eager() will now add columns into the "primary" column collection within Query._compile_context(), instead
of the "secondary" collection. This allows those columns to get wrapped within the subquery generated
by limit/offset in conjunction with an ORM-generated eager join.
Eager strategy also picks up on context.adapter in this case to deliver the columns during result load.
contains_eager() is now compatible with the subquery generated by a regular eager load
with limit/offset. [ticket:1180]
Diffstat (limited to 'test/orm/query.py')
-rw-r--r-- | test/orm/query.py | 58 |
1 files changed, 51 insertions, 7 deletions
diff --git a/test/orm/query.py b/test/orm/query.py index 5d77f2d81..12c75d94f 100644 --- a/test/orm/query.py +++ b/test/orm/query.py @@ -1234,16 +1234,27 @@ class InstancesTest(QueryTest, AssertsCompiledSQL): assert fixtures.user_address_result == l self.assert_sql_count(testing.db, go, 1) + # same thing, but alias addresses, so that the adapter generated by select_from() is wrapped within + # the adapter created by contains_eager() + adalias = addresses.alias() + query = users.select(users.c.id==7).union(users.select(users.c.id>7)).alias('ulist').outerjoin(adalias).select(use_labels=True,order_by=['ulist.id', adalias.c.id]) + def go(): + l = sess.query(User).select_from(query).options(contains_eager('addresses', alias=adalias)).all() + assert fixtures.user_address_result == l + self.assert_sql_count(testing.db, go, 1) + def test_contains_eager(self): sess = create_session() # test that contains_eager suppresses the normal outer join rendering q = sess.query(User).outerjoin(User.addresses).options(contains_eager(User.addresses)).order_by(User.id) - self.assert_compile(q.with_labels().statement, "SELECT users.id AS users_id, users.name AS users_name, "\ - "addresses.id AS addresses_id, addresses.user_id AS addresses_user_id, "\ - "addresses.email_address AS addresses_email_address FROM users LEFT OUTER JOIN addresses "\ - "ON users.id = addresses.user_id ORDER BY users.id", dialect=default.DefaultDialect()) - + self.assert_compile(q.with_labels().statement, + "SELECT addresses.id AS addresses_id, addresses.user_id AS addresses_user_id, "\ + "addresses.email_address AS addresses_email_address, users.id AS users_id, "\ + "users.name AS users_name FROM users LEFT OUTER JOIN addresses "\ + "ON users.id = addresses.user_id ORDER BY users.id" + , dialect=default.DefaultDialect()) + def go(): assert fixtures.user_address_result == q.all() self.assert_sql_count(testing.db, go, 1) @@ -1266,7 +1277,6 @@ class InstancesTest(QueryTest, AssertsCompiledSQL): sess.clear() - def go(): l = list(q.options(contains_eager(User.addresses)).instances(selectquery.execute())) assert fixtures.user_address_result[0:3] == l @@ -1306,7 +1316,6 @@ class InstancesTest(QueryTest, AssertsCompiledSQL): assert fixtures.user_address_result == l.all() self.assert_sql_count(testing.db, go, 1) sess.clear() - oalias = orders.alias('o1') ialias = items.alias('i1') @@ -1337,7 +1346,42 @@ class InstancesTest(QueryTest, AssertsCompiledSQL): self.assert_sql_count(testing.db, go, 1) sess.clear() + def test_mixed_eager_contains_with_limit(self): + sess = create_session() + + q = sess.query(User) + def go(): + # outerjoin to User.orders, offset 1/limit 2 so we get user 7 + second two orders. + # then eagerload the addresses. User + Order columns go into the subquery, address + # left outer joins to the subquery, eagerloader for User.orders applies context.adapter + # to result rows. This was [ticket:1180]. + l = q.outerjoin(User.orders).options(eagerload(User.addresses), contains_eager(User.orders)).offset(1).limit(2).all() + eq_(l, [User(id=7, + addresses=[Address(email_address=u'jack@bean.com',user_id=7,id=1)], + name=u'jack', + orders=[ + Order(address_id=1,user_id=7,description=u'order 3',isopen=1,id=3), + Order(address_id=None,user_id=7,description=u'order 5',isopen=0,id=5) + ])]) + self.assert_sql_count(testing.db, go, 1) + sess.clear() + + def go(): + # same as above, except Order is aliased, so two adapters are applied by the + # eager loader + oalias = aliased(Order) + l = q.outerjoin(User.orders, oalias).options(eagerload(User.addresses), contains_eager(User.orders, alias=oalias)).offset(1).limit(2).all() + eq_(l, [User(id=7, + addresses=[Address(email_address=u'jack@bean.com',user_id=7,id=1)], + name=u'jack', + orders=[ + Order(address_id=1,user_id=7,description=u'order 3',isopen=1,id=3), + Order(address_id=None,user_id=7,description=u'order 5',isopen=0,id=5) + ])]) + self.assert_sql_count(testing.db, go, 1) + + class MixedEntitiesTest(QueryTest): def test_values(self): |