summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-05-13 16:13:51 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-05-13 16:13:51 -0400
commit26657f92eca3cc66ade211a09008b2f82baab8ae (patch)
tree5281b6c93f9f478245dc83db45d574ca21c874ce
parentb414d82df7b810a28c85dc2323457639cb52b23f (diff)
parentf574bcf98de0d30f0a28bf82aae84098157de0f4 (diff)
downloadsqlalchemy-26657f92eca3cc66ade211a09008b2f82baab8ae.tar.gz
merge default
-rw-r--r--doc/build/changelog/changelog_08.rst10
-rw-r--r--lib/sqlalchemy/orm/util.py9
-rw-r--r--test/orm/test_eager_relations.py54
3 files changed, 72 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst
index aa8f0f878..663d3a40b 100644
--- a/doc/build/changelog/changelog_08.rst
+++ b/doc/build/changelog/changelog_08.rst
@@ -8,6 +8,16 @@
.. change::
:tags: bug, orm
+ :tickets: 2481
+
+ Fixed a regression from 0.7 caused by this ticket, which
+ made the check for recursion overflow in self-referential
+ eager joining too loose, missing a particular circumstance
+ where a subclass had lazy="joined" or "subquery" configured
+ and the load was a "with_polymorphic" against the base.
+
+ .. change::
+ :tags: bug, orm
:tickets: 2718
Fixed a regression from 0.7 where the contextmanager feature
diff --git a/lib/sqlalchemy/orm/util.py b/lib/sqlalchemy/orm/util.py
index 2a3124f4d..8a26bd834 100644
--- a/lib/sqlalchemy/orm/util.py
+++ b/lib/sqlalchemy/orm/util.py
@@ -304,7 +304,14 @@ class PathRegistry(object):
yield path[i], path[i + 1]
def contains_mapper(self, mapper):
- return mapper in self.path
+ for path_mapper in [
+ self.path[i] for i in range(0, len(self.path), 2)
+ ]:
+ if isinstance(path_mapper, mapperlib.Mapper) and \
+ path_mapper.isa(mapper):
+ return True
+ else:
+ return False
def contains(self, reg, key):
return (key, self.path) in reg._attributes
diff --git a/test/orm/test_eager_relations.py b/test/orm/test_eager_relations.py
index 41dd50e83..eb2ecce63 100644
--- a/test/orm/test_eager_relations.py
+++ b/test/orm/test_eager_relations.py
@@ -2663,4 +2663,58 @@ class CyclicalInheritingEagerTestTwo(fixtures.DeclarativeMappedTest,
d = session.query(Director).options(joinedload('*')).first()
assert len(list(session)) == 3
+class CyclicalInheritingEagerTestThree(fixtures.DeclarativeMappedTest,
+ testing.AssertsCompiledSQL):
+ __dialect__ = 'default'
+
+ @classmethod
+ def setup_classes(cls):
+ Base = cls.DeclarativeBasic
+ class PersistentObject(Base):
+ __tablename__ = 'persistent'
+ id = Column(Integer, primary_key=True,
+ test_needs_autoincrement=True)
+
+ __mapper_args__ = {'with_polymorphic': "*"}
+
+ class Director(PersistentObject):
+ __tablename__ = 'director'
+ id = Column(Integer, ForeignKey('persistent.id'), primary_key=True)
+ other_id = Column(Integer, ForeignKey('persistent.id'))
+ name = Column(String(50))
+ other = relationship(PersistentObject,
+ primaryjoin=other_id==PersistentObject.id,
+ lazy=False)
+ __mapper_args__ = {"inherit_condition": id==PersistentObject.id}
+
+ def test_gen_query_nodepth(self):
+ PersistentObject = self.classes.PersistentObject
+ sess = create_session()
+ self.assert_compile(
+ sess.query(PersistentObject),
+ "SELECT persistent.id AS persistent_id, director.id AS director_id,"
+ " director.other_id AS director_other_id, "
+ "director.name AS director_name FROM persistent "
+ "LEFT OUTER JOIN director ON director.id = persistent.id"
+ )
+ def test_gen_query_depth(self):
+ PersistentObject = self.classes.PersistentObject
+ Director = self.classes.Director
+ sess = create_session()
+ self.assert_compile(
+ sess.query(PersistentObject).options(joinedload(Director.other, join_depth=1)),
+ "SELECT persistent.id AS persistent_id, director.id AS director_id, "
+ "director.other_id AS director_other_id, "
+ "director.name AS director_name, anon_1.persistent_id AS "
+ "anon_1_persistent_id, anon_1.director_id AS anon_1_director_id, "
+ "anon_1.director_other_id AS anon_1_director_other_id, "
+ "anon_1.director_name AS anon_1_director_name "
+ "FROM persistent LEFT OUTER JOIN director ON director.id = persistent.id "
+ "LEFT OUTER JOIN (SELECT persistent.id AS persistent_id, "
+ "director.id AS director_id, director.other_id AS director_other_id, "
+ "director.name AS director_name "
+ "FROM persistent LEFT OUTER JOIN director ON "
+ "director.id = persistent.id) "
+ "AS anon_1 ON director.other_id = anon_1.persistent_id"
+ )