From 7d96ad4d535dc02a8ab1384df1db94dea2a045b5 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 12 Dec 2015 21:07:25 -0500 Subject: [PATCH] - Fixed bug where use of the :meth:`.Query.select_from` method would cause a subsequent call to the :meth:`.Query.with_parent` method to fail. fixes #3606 - add mark-as-fail test for #3607 --- doc/build/changelog/changelog_10.rst | 12 ++++++++++ lib/sqlalchemy/orm/query.py | 6 ++++- lib/sqlalchemy/testing/exclusions.py | 4 ++-- test/orm/test_query.py | 33 ++++++++++++++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/doc/build/changelog/changelog_10.rst b/doc/build/changelog/changelog_10.rst index 30c58fa7f8..950046cd0e 100644 --- a/doc/build/changelog/changelog_10.rst +++ b/doc/build/changelog/changelog_10.rst @@ -15,6 +15,18 @@ .. include:: changelog_07.rst :start-line: 5 +.. changelog:: + :version: 1.0.11 + + .. change:: + :tags: bug, orm + :tickets: 3606 + :versions: 1.1.0b1 + + Fixed bug where use of the :meth:`.Query.select_from` method would + cause a subsequent call to the :meth:`.Query.with_parent` method to + fail. + .. changelog:: :version: 1.0.10 :released: December 11, 2015 diff --git a/lib/sqlalchemy/orm/query.py b/lib/sqlalchemy/orm/query.py index 6f4373ec53..e1b920bbb4 100644 --- a/lib/sqlalchemy/orm/query.py +++ b/lib/sqlalchemy/orm/query.py @@ -289,6 +289,8 @@ class Query(object): return self._entities[0] def _mapper_zero(self): + # TODO: self._select_from_entity is not a mapper + # so this method is misnamed return self._select_from_entity \ if self._select_from_entity is not None \ else self._entity_zero().entity_zero @@ -942,11 +944,13 @@ class Query(object): """ if property is None: + mapper_zero = inspect(self._mapper_zero()).mapper + mapper = object_mapper(instance) for prop in mapper.iterate_properties: if isinstance(prop, properties.RelationshipProperty) and \ - prop.mapper is self._mapper_zero(): + prop.mapper is mapper_zero: property = prop break else: diff --git a/lib/sqlalchemy/testing/exclusions.py b/lib/sqlalchemy/testing/exclusions.py index 2a5b4aa632..5d7baeb9c1 100644 --- a/lib/sqlalchemy/testing/exclusions.py +++ b/lib/sqlalchemy/testing/exclusions.py @@ -398,8 +398,8 @@ def closed(): return skip_if(BooleanPredicate(True, "marked as skip")) -def fails(): - return fails_if(BooleanPredicate(True, "expected to fail")) +def fails(reason=None): + return fails_if(BooleanPredicate(True, reason or "expected to fail")) @decorator diff --git a/test/orm/test_query.py b/test/orm/test_query.py index a373f14829..d2f9e4a66b 100644 --- a/test/orm/test_query.py +++ b/test/orm/test_query.py @@ -3216,6 +3216,39 @@ class ParentTest(QueryTest, AssertsCompiledSQL): # sess.query(Order).with_parent(None, property='addresses').all() # == [Order(description="order 5")] + def test_select_from(self): + User, Address = self.classes.User, self.classes.Address + + sess = create_session() + u1 = sess.query(User).get(7) + q = sess.query(Address).select_from(Address).with_parent(u1) + self.assert_compile( + q, + "SELECT addresses.id AS addresses_id, " + "addresses.user_id AS addresses_user_id, " + "addresses.email_address AS addresses_email_address " + "FROM addresses WHERE :param_1 = addresses.user_id", + {'param_1': 7} + ) + + @testing.fails("issue #3607") + def test_select_from_alias(self): + User, Address = self.classes.User, self.classes.Address + + sess = create_session() + u1 = sess.query(User).get(7) + a1 = aliased(Address) + q = sess.query(a1).with_parent(u1) + self.assert_compile( + q, + "SELECT addresses_1.id AS addresses_1_id, " + "addresses_1.user_id AS addresses_1_user_id, " + "addresses_1.email_address AS addresses_1_email_address " + "FROM addresses AS addresses_1 " + "WHERE :param_1 = addresses_1.user_id", + {'param_1': 7} + ) + def test_noparent(self): Item, User = self.classes.Item, self.classes.User -- 2.47.2