]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed bug where query.join() + aliased=True
authorMike Bayer <mike_mp@zzzcomputing.com>
Sat, 30 Jul 2011 16:12:32 +0000 (12:12 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sat, 30 Jul 2011 16:12:32 +0000 (12:12 -0400)
from a joined-inh structure to itself on
relationship() with join condition on the child
table would convert the lead entity into the
joined one inappropriately.  [ticket:2234]
Also in 0.6.9.

CHANGES
lib/sqlalchemy/orm/query.py
test/orm/inheritance/test_query.py

diff --git a/CHANGES b/CHANGES
index 9a39c613e082d6c5059cf3d84a28fa84afb82d93..59139fd992acb844aaa41e2134b73cba9f73de50 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -38,6 +38,13 @@ CHANGES
     a fix for multiply-nested any()/has() constructs 
     against a joined table structure.  [ticket:2195]
 
+  - Fixed bug where query.join() + aliased=True
+    from a joined-inh structure to itself on 
+    relationship() with join condition on the child
+    table would convert the lead entity into the 
+    joined one inappropriately.  [ticket:2234]
+    Also in 0.6.9.
+
   - Fixed regression from 0.6 where Session.add()
     against an object which contained None in a
     collection would raise an internal exception.
index a3b13abb27729e5d81ab2378964f29f1326798da..d9c67d56cde1f542793b2bb1b2b5a08bdc7ea598 100644 (file)
@@ -1535,7 +1535,7 @@ class Query(object):
         # which is intended to wrap a the right side in a subquery,
         # ensure that columns retrieved from this target in the result
         # set are also adapted.
-        if aliased_entity:
+        if aliased_entity and not create_aliases:
             self.__mapper_loads_polymorphically_with(
                         right_mapper,
                         ORMAdapter(
index 23052f9977e9ff0d74020244b98ab5f2c83ec57d..2560d228438fd1c75b5b5a46776d51ebdbfc8950 100644 (file)
@@ -1083,7 +1083,119 @@ class SelfReferentialJ2JTest(fixtures.MappedTest):
             [m1]
         )
 
+class SelfReferentialJ2JSelfTest(fixtures.MappedTest):
+    run_setup_mappers = 'once'
+
+    @classmethod
+    def define_tables(cls, metadata):
+        people = Table('people', metadata,
+           Column('person_id', Integer, 
+                        primary_key=True, test_needs_autoincrement=True),
+           Column('name', String(50)),
+           Column('type', String(30)))
+
+        engineers = Table('engineers', metadata,
+           Column('person_id', Integer, 
+                    ForeignKey('people.person_id'), primary_key=True),
+           Column('reports_to_id', Integer, 
+                    ForeignKey('engineers.person_id'))
+          )
+
+
+    @classmethod
+    def setup_mappers(cls):
+        engineers, people = (cls.tables.engineers,
+                                cls.tables.people)
+
+        mapper(Person, people, polymorphic_on=people.c.type, 
+                            polymorphic_identity='person')
+
+        mapper(Engineer, engineers, inherits=Person, 
+          polymorphic_identity='engineer', properties={
+          'reports_to':relationship(Engineer, 
+                            primaryjoin=engineers.c.person_id==engineers.c.reports_to_id, 
+                            backref='engineers',
+                            remote_side=engineers.c.person_id)
+        })
 
+    def _two_obj_fixture(self):
+        e1 = Engineer(name='wally')
+        e2 = Engineer(name='dilbert', 
+                        reports_to=e1)
+        sess = Session()
+        sess.add_all([e1, e2])
+        sess.commit()
+        return sess
+
+    def _five_obj_fixture(self):
+        sess =Session()
+        e1, e2, e3, e4, e5 = [
+            Engineer(name='e%d' % (i + 1)) for i in xrange(5)
+        ]
+        e3.reports_to=e1
+        e4.reports_to=e2
+        sess.add_all([e1, e2, e3, e4, e5])
+        sess.commit()
+        return sess
+
+    def test_has(self):
+        sess = self._two_obj_fixture()
+
+        eq_(
+            sess.query(Engineer).
+                filter(Engineer.reports_to.has(Engineer.name=='wally')).
+                first(), 
+            Engineer(name='dilbert'))
+
+    def test_join_explicit_alias(self):
+        sess = self._five_obj_fixture()
+
+        ea = aliased(Engineer)
+        eq_(
+            sess.query(Engineer).
+                join(ea, Engineer.engineers).
+                filter(Engineer.name=='e1').all(),
+            [Engineer(name='e1')]
+        )
+
+    def test_join_aliased_flag_one(self):
+        sess = self._two_obj_fixture()
+
+        eq_(
+            sess.query(Engineer).
+                join('reports_to', aliased=True).
+                filter(Engineer.name=='wally').first(), 
+            Engineer(name='dilbert')
+        )
+
+    def test_join_aliased_flag_two(self):
+        sess = self._five_obj_fixture()
+
+        eq_(
+            sess.query(Engineer).
+                join(Engineer.engineers, aliased=True).
+                filter(Engineer.name=='e4').all(),
+            [Engineer(name='e2')]
+        )
+
+
+    def test_relationship_compare(self):
+        sess = self._five_obj_fixture()
+
+        eq_(
+            sess.query(Engineer).
+                join(Engineer.engineers, aliased=True).
+                filter(Engineer.reports_to==None).all(), 
+            []
+        )
+
+        e1 = sess.query(Engineer).filter_by(name='e1').one()
+        eq_(
+            sess.query(Engineer).
+                join(Engineer.engineers, aliased=True).
+                filter(Engineer.reports_to==e1).all(), 
+            [e1]
+        )
 
 class M2MFilterTest(fixtures.MappedTest):
     run_setup_mappers = 'once'