summaryrefslogtreecommitdiff
path: root/test/ext/declarative.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2008-11-03 02:52:30 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2008-11-03 02:52:30 +0000
commita5dfbeedb9f7ae148081d1dbc3e91e876526eb90 (patch)
tree070cede0b9a927c5672a7b847113a9947a2726ce /test/ext/declarative.py
parent334d5118bb7bcf6fcf052c1b12182009fe54ebef (diff)
downloadsqlalchemy-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.py72
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