]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- Fixed explicit, self-referential joins between two
authorMike Bayer <mike_mp@zzzcomputing.com>
Sun, 22 Jun 2008 19:02:19 +0000 (19:02 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Sun, 22 Jun 2008 19:02:19 +0000 (19:02 +0000)
joined-table inheritance mappers when using
query.join(cls, aliased=True).  [ticket:1082]

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

diff --git a/CHANGES b/CHANGES
index d34bf8b810c9cd3426fd09f0b54db03144b9125b..fc32ab2d0e8b4f8e7d313453f0ff9c9fd4da45c9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -20,6 +20,10 @@ CHANGES
       locally modified, so that they are refreshed with the
       most recent data upon access.  [ticket:887]
 
+    - Fixed explicit, self-referential joins between two 
+      joined-table inheritance mappers when using 
+      query.join(cls, aliased=True).  [ticket:1082]
+      
 0.5beta1
 ========
     - An ongoing document describing the changes from 0.4 to 0.5
index 51c57ca30297a7be21bebdf01957e24308c05a95..37463ef10df60526714ee72ef27f26cd4ef1eade 100644 (file)
@@ -842,14 +842,14 @@ class Query(object):
                     right_entity = aliased(right_mapper, right_selectable)
                     alias_criterion = True
 
-                elif right_mapper.with_polymorphic or isinstance(right_mapper.mapped_table, expression.Join):
-                    aliased_entity = True
+                elif create_aliases:
                     right_entity = aliased(right_mapper)
                     alias_criterion = True
-                
-                elif create_aliases:
+
+                elif right_mapper.with_polymorphic or isinstance(right_mapper.mapped_table, expression.Join):
                     right_entity = aliased(right_mapper)
                     alias_criterion = True
+                    aliased_entity = True
                     
                 elif prop:
                     if prop.table in self.__currenttables:
@@ -873,7 +873,7 @@ class Query(object):
             if alias_criterion: 
                 self._filter_aliases = ORMAdapter(right_entity, 
                         equivalents=right_mapper._equivalent_columns, chain_to=self._filter_aliases)
-
+                
                 if aliased_entity:
                     self.__mapper_loads_polymorphically_with(right_mapper, ORMAdapter(right_entity, equivalents=right_mapper._equivalent_columns))
 
@@ -1567,7 +1567,7 @@ class _MapperEntity(_QueryEntity):
 
     def setup_context(self, query, context):
         adapter = self._get_entity_clauses(query, context)
-
+        
         context.froms.append(self.selectable)
 
         if context.order_by is False and self.mapper.order_by:
index c706acf6e16cf977108323d51ebafc27504237cd..678513dbc2f713f09b6fc09829a6c080ee7a00c9 100644 (file)
@@ -653,7 +653,7 @@ for select_type in ('', 'Polymorphic', 'Unions', 'AliasedJoins', 'Joins'):
     
 del testclass
 
-class SelfReferentialTest(ORMTest):
+class SelfReferentialTestJoinedToBase(ORMTest):
     keep_mappers = True
     
     def define_tables(self, metadata):
@@ -706,7 +706,62 @@ class SelfReferentialTest(ORMTest):
         sess.flush()
         sess.clear()
         
-        self.assertEquals(sess.query(Engineer).join('reports_to', aliased=True).filter(Person.name=='dogbert').first(), Engineer(name='dilbert'))
+        self.assertEquals(
+            sess.query(Engineer).join('reports_to', aliased=True).filter(Person.name=='dogbert').first(), 
+            Engineer(name='dilbert'))
+
+class SelfReferentialTestJoinedToJoined(ORMTest):
+    keep_mappers = True
+
+    def define_tables(self, metadata):
+        global people, engineers
+        people = Table('people', metadata,
+           Column('person_id', Integer, Sequence('person_id_seq', optional=True), primary_key=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('primary_language', String(50)),
+           Column('reports_to_id', Integer, ForeignKey('managers.person_id'))
+          )
+          
+        managers = Table('managers', metadata,
+            Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
+        )
+
+        mapper(Person, people, polymorphic_on=people.c.type, polymorphic_identity='person')
+        mapper(Manager, managers, inherits=Person, polymorphic_identity='manager')
+        
+        mapper(Engineer, engineers, inherits=Person, 
+          polymorphic_identity='engineer', properties={
+          'reports_to':relation(Manager, primaryjoin=managers.c.person_id==engineers.c.reports_to_id)
+        })
+
+    def test_has(self):
+
+        m1 = Manager(name='dogbert')
+        e1 = Engineer(name='dilbert', primary_language='java', reports_to=m1)
+        sess = create_session()
+        sess.save(m1)
+        sess.save(e1)
+        sess.flush()
+        sess.clear()
+
+        self.assertEquals(sess.query(Engineer).filter(Engineer.reports_to.has(Manager.name=='dogbert')).first(), Engineer(name='dilbert'))
+
+    def test_join(self):
+        m1 = Manager(name='dogbert')
+        e1 = Engineer(name='dilbert', primary_language='java', reports_to=m1)
+        sess = create_session()
+        sess.save(m1)
+        sess.save(e1)
+        sess.flush()
+        sess.clear()
+
+        self.assertEquals(
+            sess.query(Engineer).join('reports_to', aliased=True).filter(Manager.name=='dogbert').first(), 
+            Engineer(name='dilbert'))
         
 
 class M2MFilterTest(ORMTest):