diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-11-03 02:52:30 +0000 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2008-11-03 02:52:30 +0000 |
commit | a5dfbeedb9f7ae148081d1dbc3e91e876526eb90 (patch) | |
tree | 070cede0b9a927c5672a7b847113a9947a2726ce /test/ext/declarative.py | |
parent | 334d5118bb7bcf6fcf052c1b12182009fe54ebef (diff) | |
download | sqlalchemy-a5dfbeedb9f7ae148081d1dbc3e91e876526eb90.tar.gz |
- Improved the behavior of aliased() objects such that they more
accurately adapt the expressions generated, which helps
particularly with self-referential comparisons. [ticket:1171]
- Fixed bug involving primaryjoin/secondaryjoin conditions
constructed from class-bound attributes (as often occurs
when using declarative), which later would be inappropriately
aliased by Query, particularly with the various EXISTS
based comparators.
Diffstat (limited to 'test/ext/declarative.py')
-rw-r--r-- | test/ext/declarative.py | 72 |
1 files changed, 71 insertions, 1 deletions
diff --git a/test/ext/declarative.py b/test/ext/declarative.py index 772dca8e1..1c088d143 100644 --- a/test/ext/declarative.py +++ b/test/ext/declarative.py @@ -6,7 +6,7 @@ from testlib import sa, testing from testlib.sa import MetaData, Table, Column, Integer, String, ForeignKey, ForeignKeyConstraint, asc from testlib.sa.orm import relation, create_session, class_mapper, eagerload, compile_mappers, backref from testlib.testing import eq_ -from orm._base import ComparableEntity +from orm._base import ComparableEntity, MappedTest class DeclarativeTest(testing.TestBase, testing.AssertsExecutionResults): @@ -784,7 +784,77 @@ class DeclarativeTest(testing.TestBase, testing.AssertsExecutionResults): finally: meta.drop_all() +def produce_test(inline, stringbased): + class ExplicitJoinTest(testing.ORMTest): + + def define_tables(self, metadata): + global User, Address + Base = decl.declarative_base(metadata=metadata) + class User(Base, ComparableEntity): + __tablename__ = 'users' + id = Column(Integer, primary_key=True) + name = Column(String(50)) + + class Address(Base, ComparableEntity): + __tablename__ = 'addresses' + id = Column(Integer, primary_key=True) + email = Column(String(50)) + user_id = Column(Integer, ForeignKey('users.id')) + if inline: + if stringbased: + user = relation("User", primaryjoin="User.id==Address.user_id", backref="addresses") + else: + user = relation(User, primaryjoin=User.id==user_id, backref="addresses") + + if not inline: + compile_mappers() + if stringbased: + Address.user = relation("User", primaryjoin="User.id==Address.user_id", backref="addresses") + else: + Address.user = relation(User, primaryjoin=User.id==Address.user_id, backref="addresses") + + def insert_data(self): + params = [dict(zip(('id', 'name'), column_values)) for column_values in + [(7, 'jack'), + (8, 'ed'), + (9, 'fred'), + (10, 'chuck')] + ] + User.__table__.insert().execute(params) + + Address.__table__.insert().execute( + [dict(zip(('id', 'user_id', 'email'), column_values)) for column_values in + [(1, 7, "jack@bean.com"), + (2, 8, "ed@wood.com"), + (3, 8, "ed@bettyboop.com"), + (4, 8, "ed@lala.com"), + (5, 9, "fred@fred.com")] + ] + ) + + def test_aliased_join(self): + # this query will screw up if the aliasing + # enabled in query.join() gets applied to the right half of the join condition inside the any(). + # the join condition inside of any() comes from the "primaryjoin" of the relation, + # and should not be annotated with _orm_adapt. PropertyLoader.Comparator will annotate + # the left side with _orm_adapt, though. + sess = create_session() + eq_( + sess.query(User).join(User.addresses, aliased=True). + filter(Address.email=='ed@wood.com').filter(User.addresses.any(Address.email=='jack@bean.com')).all(), + [] + ) + + ExplicitJoinTest.__name__ = "ExplicitJoinTest%s%s" % (inline and 'Inline' or 'Separate', stringbased and 'String' or 'Literal') + return ExplicitJoinTest + +for inline in (True, False): + for stringbased in (True, False): + testclass = produce_test(inline, stringbased) + exec("%s = testclass" % testclass.__name__) + del testclass + class DeclarativeReflectionTest(testing.TestBase): def setUpAll(self): global reflection_metadata |