From: Mike Bayer Date: Wed, 24 Mar 2010 17:19:34 +0000 (-0400) Subject: everything everything passes on this one. still want to get rid of that hack tho. X-Git-Tag: rel_0_6beta3~12^2~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9c68542116285c94bc2584edcd25fec6cf305eba;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git everything everything passes on this one. still want to get rid of that hack tho. --- diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index c56804847a..d0827df84b 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -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)) diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py index 92b560cd9c..cf1839df70 100644 --- a/lib/sqlalchemy/orm/strategies.py +++ b/lib/sqlalchemy/orm/strategies.py @@ -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 diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py index 1be8156862..28b7e4397c 100644 --- a/test/orm/test_subquery_relations.py +++ b/test/orm/test_subquery_relations.py @@ -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 !