From: Mike Bayer Date: Wed, 13 Apr 2011 23:35:23 +0000 (-0400) Subject: - a "having" clause would be copied from the X-Git-Tag: rel_0_6_7~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=edae4fb582be6ebb422e06b6e6fabc2c1440c9df;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - a "having" clause would be copied from the inside to the outside query if from_self() were used. [ticket:2130]. --- diff --git a/CHANGES b/CHANGES index fcc94ff4b1..ec6ebb38e0 100644 --- a/CHANGES +++ b/CHANGES @@ -56,6 +56,10 @@ CHANGES change. Thanks to Richard Murri for the test case + patch. [ticket:2123] + - a "having" clause would be copied from the + inside to the outside query if from_self() + were used. [ticket:2130]. + - sql - Column.copy(), as used in table.tometadata(), copies the 'doc' attribute. [ticket:2028] diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 64ea7455b5..7f3af5a023 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -756,9 +756,12 @@ class Query(object): @_generative() def _from_selectable(self, fromclause): - for attr in ('_statement', '_criterion', '_order_by', '_group_by', - '_limit', '_offset', '_joinpath', '_joinpoint', - '_distinct' + for attr in ( + '_statement', '_criterion', + '_order_by', '_group_by', + '_limit', '_offset', + '_joinpath', '_joinpoint', + '_distinct', '_having' ): self.__dict__.pop(attr, None) self._set_select_from(fromclause) diff --git a/test/orm/test_query.py b/test/orm/test_query.py index 4b4d8a7cd7..8c30b8c8dc 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -998,10 +998,17 @@ class FilterTest(QueryTest): class FromSelfTest(QueryTest, AssertsCompiledSQL): def test_filter(self): - assert [User(id=8), User(id=9)] == create_session().query(User).filter(User.id.in_([8,9])).from_self().all() - - assert [User(id=8), User(id=9)] == create_session().query(User).order_by(User.id).slice(1,3).from_self().all() - assert [User(id=8)] == list(create_session().query(User).filter(User.id.in_([8,9])).from_self().order_by(User.id)[0:1]) + assert [User(id=8), User(id=9)] == \ + create_session().query(User).\ + filter(User.id.in_([8,9])).from_self().all() + + assert [User(id=8), User(id=9)] == \ + create_session().query(User).\ + order_by(User.id).slice(1,3).from_self().all() + assert [User(id=8)] == \ + list(create_session().query(User).\ + filter(User.id.in_([8,9])).from_self().\ + order_by(User.id)[0:1]) def test_join(self): assert [ @@ -1009,35 +1016,62 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL): (User(id=8), Address(id=3)), (User(id=8), Address(id=4)), (User(id=9), Address(id=5)) - ] == create_session().query(User).filter(User.id.in_([8,9])).from_self().\ - join('addresses').add_entity(Address).order_by(User.id, Address.id).all() + ] == create_session().query(User).\ + filter(User.id.in_([8,9])).from_self().\ + join('addresses').add_entity(Address).\ + order_by(User.id, Address.id).all() def test_group_by(self): eq_( - create_session().query(Address.user_id, func.count(Address.id).label('count')).\ - group_by(Address.user_id).order_by(Address.user_id).all(), + create_session().query(Address.user_id, + func.count(Address.id).label('count')).\ + group_by(Address.user_id). + order_by(Address.user_id).all(), [(7, 1), (8, 3), (9, 1)] ) eq_( - create_session().query(Address.user_id, Address.id).\ - from_self(Address.user_id, func.count(Address.id)).\ - group_by(Address.user_id).order_by(Address.user_id).all(), + create_session().query(Address.user_id, + Address.id).\ + from_self(Address.user_id, + func.count(Address.id)).\ + group_by(Address.user_id). + order_by(Address.user_id).all(), [(7, 1), (8, 3), (9, 1)] ) + def test_having(self): + s = create_session() + + self.assert_compile( + s.query(User.id).group_by(User.id).having(User.id>5). + from_self(), + "SELECT anon_1.users_id AS anon_1_users_id FROM " + "(SELECT users.id AS users_id FROM users GROUP " + "BY users.id HAVING users.id > :id_1) AS anon_1", + use_default_dialect=True + ) + def test_no_joinedload(self): - """test that joinedloads are pushed outwards and not rendered in subqueries.""" + """test that joinedloads are pushed outwards and not + rendered in subqueries.""" s = create_session() oracle_as = not testing.against('oracle') and "AS " or "" self.assert_compile( - s.query(User).options(joinedload(User.addresses)).from_self().statement, - "SELECT anon_1.users_id, anon_1.users_name, addresses_1.id, addresses_1.user_id, "\ - "addresses_1.email_address FROM (SELECT users.id AS users_id, users.name AS users_name FROM users) %(oracle_as)sanon_1 "\ - "LEFT OUTER JOIN addresses %(oracle_as)saddresses_1 ON anon_1.users_id = addresses_1.user_id ORDER BY addresses_1.id" % { + s.query(User). + options(joinedload(User.addresses)). + from_self().statement, + "SELECT anon_1.users_id, anon_1.users_name, " + "addresses_1.id, addresses_1.user_id, " + "addresses_1.email_address FROM (SELECT users.id " + "AS users_id, users.name AS users_name FROM users) " + "%(oracle_as)sanon_1 " + "LEFT OUTER JOIN addresses %(oracle_as)saddresses_1 " + "ON anon_1.users_id = addresses_1.user_id ORDER " + "BY addresses_1.id" % { 'oracle_as':oracle_as } ) @@ -1049,7 +1083,8 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL): ualias = aliased(User) eq_( - s.query(User, ualias).filter(User.id > ualias.id).from_self(User.name, ualias.name). + s.query(User, ualias).filter(User.id > ualias.id). + from_self(User.name, ualias.name). order_by(User.name, ualias.name).all(), [ (u'chuck', u'ed'), @@ -1062,14 +1097,17 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL): ) eq_( - s.query(User, ualias).filter(User.id > ualias.id).from_self(User.name, ualias.name).filter(ualias.name=='ed')\ + s.query(User, ualias).filter(User.id > ualias.id). + from_self(User.name, ualias.name).filter(ualias.name=='ed')\ .order_by(User.name, ualias.name).all(), [(u'chuck', u'ed'), (u'fred', u'ed')] ) eq_( - s.query(User, ualias).filter(User.id > ualias.id).from_self(ualias.name, Address.email_address). - join(ualias.addresses).order_by(ualias.name, Address.email_address).all(), + s.query(User, ualias).filter(User.id > ualias.id). + from_self(ualias.name, Address.email_address). + join(ualias.addresses). + order_by(ualias.name, Address.email_address).all(), [ (u'ed', u'fred@fred.com'), (u'jack', u'ed@bettyboop.com'), @@ -1083,7 +1121,9 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL): sess = create_session() eq_( - sess.query(User, Address).filter(User.id==Address.user_id).filter(Address.id.in_([2, 5])).from_self().all(), + sess.query(User, Address). + filter(User.id==Address.user_id). + filter(Address.id.in_([2, 5])).from_self().all(), [ (User(id=8), Address(id=2)), (User(id=9), Address(id=5)) @@ -1091,7 +1131,10 @@ class FromSelfTest(QueryTest, AssertsCompiledSQL): ) eq_( - sess.query(User, Address).filter(User.id==Address.user_id).filter(Address.id.in_([2, 5])).from_self().options(joinedload('addresses')).first(), + sess.query(User, Address). + filter(User.id==Address.user_id). + filter(Address.id.in_([2, 5])). + from_self().options(joinedload('addresses')).first(), # order_by(User.id, Address.id).first(), (User(id=8, addresses=[Address(), Address(), Address()]), Address(id=2)),