]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
everything everything passes on this one. still want to get rid of that hack tho.
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 24 Mar 2010 17:19:34 +0000 (13:19 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 24 Mar 2010 17:19:34 +0000 (13:19 -0400)
lib/sqlalchemy/orm/query.py
lib/sqlalchemy/orm/strategies.py
test/orm/test_subquery_relations.py

index c56804847a56cbebc1ad2b9853b76b357d1bd77e..d0827df84b39d9660f0061a18b661c1e5ce8beee 100644 (file)
@@ -1069,7 +1069,8 @@ class Query(object):
             left = self._joinpoint_zero()
 
         if left is right and \
-                not create_aliases:
+                not create_aliases and \
+                not self._entity_zero()._subq_aliasing:
             raise sa_exc.InvalidRequestError(
                         "Can't construct a join from %s to %s, they are the same entity" % 
                         (left, right))
index 92b560cd9c3c03666443d55e0df45066ee915c4c..cf1839df702bc86ae1774d3b01b85bee0edf9db0 100644 (file)
@@ -699,8 +699,6 @@ class SubqueryLoader(AbstractRelationshipLoader):
         # for the significant columns, not order
         # by anything.
         q = orig_query._clone()
-#        q._attributes = {}
-#        q._attributes[("orig_query", SubqueryLoader)] = orig_query
         q._set_entities(q._adapt_col_list(leftmost_attr))
         if q._limit is None and q._offset is None:
             q._order_by = None
@@ -708,19 +706,15 @@ class SubqueryLoader(AbstractRelationshipLoader):
         embed_q = q.with_labels().subquery()
         
         q = q.session.query(self.mapper)
+        
+        # magic hardcody thing.  TODO: dammit
+        q._entities[0]._subq_aliasing = True
         q._attributes = {}
         q._attributes[("orig_query", SubqueryLoader)] = orig_query
         
         left_alias = mapperutil.AliasedClass(leftmost_mapper, embed_q)
         q = q.select_from(left_alias)
         
-#        q = q.from_self(self.mapper)
-        
-        # TODO: this is currently a magic hardcody
-        # flag on _MapperEntity.  we should find 
-        # a way to turn it into public functionality.
-#        q._entities[0]._subq_aliasing = True
-
         q._attributes[('subquery_path', None)] = subq_path
 
         to_join = [
@@ -729,10 +723,6 @@ class SubqueryLoader(AbstractRelationshipLoader):
                 ]
 
         if len(to_join) < 2:
-#            local_attr = [
-#                self.parent._get_col_to_prop(c).class_attribute
-#                for c in local_cols
-#            ]
             local_attr = [
                 getattr(left_alias, self.parent._get_col_to_prop(c).key)
                 for c in local_cols
index 1be81568628c422c5e207b38f044c55b9db1570f..28b7e4397c27d9b6cec14545d82f75ca456622fa 100644 (file)
@@ -5,7 +5,7 @@ from sqlalchemy import Integer, String, ForeignKey
 from sqlalchemy.orm import backref, subqueryload, subqueryload_all, \
                 mapper, relationship, clear_mappers,\
                 create_session, lazyload, aliased, eagerload,\
-                deferred
+                deferred, undefer
 from sqlalchemy.test.testing import eq_, assert_raises
 from sqlalchemy.test.assertsql import CompiledSQL
 from test.orm import _base, _fixtures
@@ -630,7 +630,7 @@ class SelfReferentialTest(_base.MappedTest):
 
 
     @testing.resolve_artifact_names
-    def _test_lazy_fallback_doesnt_affect_eager(self):
+    def test_lazy_fallback_doesnt_affect_eager(self):
         class Node(_base.ComparableEntity):
             def append(self, node):
                 self.children.append(node)
@@ -660,10 +660,10 @@ class SelfReferentialTest(_base.MappedTest):
                 Node(data='n122'),
                 Node(data='n123')
             ], list(n12.children))
-        self.assert_sql_count(testing.db, go, 1)
+        self.assert_sql_count(testing.db, go, 4)
 
     @testing.resolve_artifact_names
-    def _test_with_deferred(self):
+    def test_with_deferred(self):
         class Node(_base.ComparableEntity):
             def append(self, node):
                 self.children.append(node)
@@ -686,14 +686,14 @@ class SelfReferentialTest(_base.MappedTest):
                 Node(data='n1', children=[Node(data='n11'), Node(data='n12')]),
                 sess.query(Node).order_by(Node.id).first(),
                 )
-        self.assert_sql_count(testing.db, go, 4)
+        self.assert_sql_count(testing.db, go, 6)
 
         sess.expunge_all()
 
         def go():
             eq_(Node(data='n1', children=[Node(data='n11'), Node(data='n12')]),
                 sess.query(Node).options(undefer('data')).order_by(Node.id).first())
-        self.assert_sql_count(testing.db, go, 3)
+        self.assert_sql_count(testing.db, go, 5)
 
         sess.expunge_all()
 
@@ -701,17 +701,17 @@ class SelfReferentialTest(_base.MappedTest):
             eq_(Node(data='n1', children=[Node(data='n11'), Node(data='n12')]),
                 sess.query(Node).options(undefer('data'),
                                             undefer('children.data')).first())
-        self.assert_sql_count(testing.db, go, 1)
+        self.assert_sql_count(testing.db, go, 3)
 
 
     @testing.resolve_artifact_names
-    def _test_options(self):
+    def test_options(self):
         class Node(_base.ComparableEntity):
             def append(self, node):
                 self.children.append(node)
 
         mapper(Node, nodes, properties={
-            'children':relationship(Node, lazy=True, order_by=nodes.c.id)
+            'children':relationship(Node, order_by=nodes.c.id)
         }, order_by=nodes.c.id)
         sess = create_session()
         n1 = Node(data='n1')
@@ -726,7 +726,7 @@ class SelfReferentialTest(_base.MappedTest):
         sess.expunge_all()
         def go():
             d = sess.query(Node).filter_by(data='n1').\
-                        options(eagerload('children.children')).first()
+                        options(subqueryload('children.children')).first()
             eq_(Node(data='n1', children=[
                 Node(data='n11'),
                 Node(data='n12', children=[
@@ -736,11 +736,12 @@ class SelfReferentialTest(_base.MappedTest):
                 ]),
                 Node(data='n13')
             ]), d)
-        self.assert_sql_count(testing.db, go, 2)
+        self.assert_sql_count(testing.db, go, 3)
 
     @testing.fails_on('maxdb', 'FIXME: unknown')
     @testing.resolve_artifact_names
-    def _test_no_depth(self):
+    def test_no_depth(self):
+        """no join depth is set, so no eager loading occurs."""
         class Node(_base.ComparableEntity):
             def append(self, node):
                 self.children.append(node)
@@ -756,34 +757,28 @@ class SelfReferentialTest(_base.MappedTest):
         n1.children[1].append(Node(data='n121'))
         n1.children[1].append(Node(data='n122'))
         n1.children[1].append(Node(data='n123'))
+        n2 = Node(data='n2')
+        n2.append(Node(data='n21'))
         sess.add(n1)
+        sess.add(n2)
         sess.flush()
         sess.expunge_all()
         def go():
-            d = sess.query(Node).filter_by(data='n1').first()
-            eq_(Node(data='n1', children=[
-                Node(data='n11'),
-                Node(data='n12', children=[
-                    Node(data='n121'),
-                    Node(data='n122'),
-                    Node(data='n123')
+            d = sess.query(Node).filter(Node.data.in_(['n1', 'n2'])).order_by(Node.data).all()
+            eq_([
+                Node(data='n1', children=[
+                    Node(data='n11'),
+                    Node(data='n12', children=[
+                        Node(data='n121'),
+                        Node(data='n122'),
+                        Node(data='n123')
+                    ]),
+                    Node(data='n13')
                 ]),
-                Node(data='n13')
-            ]), d)
-        self.assert_sql_count(testing.db, go, 3)
+                Node(data='n2', children=[
+                    Node(data='n21')
+                ])
+            ], d)
+        self.assert_sql_count(testing.db, go, 4)
 
-    # TODO: all the tests in test_eager_relations
-    
-    # TODO: ensure state stuff works out OK, existing objects/collections
-    # don't get inappropriately whacked, etc.
-    
-    # TODO: subquery loading with eagerloads on those collections ???
-    
-    # TODO: eagerloading of child objects with subquery loading on those ???
-    
-    # TODO: lazy loads leading into subq loads ??
-    
-    # TODO: e.g. all kinds of path combos need to be tested
-    
-    # TODO: joined table inh !