summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Koval <kovalidis@gmail.com>2013-10-11 23:49:26 +0300
committerAlexander Koval <kovalidis@gmail.com>2013-10-11 23:49:26 +0300
commit9e61d9eb51eb38da95b7df330b16db0fb4b0b1b4 (patch)
treec9a47980906a73d87d7238eda1a7ba47b55f052b
parenta84af718858d63e123814e4c9683c8ce2ab11dee (diff)
downloadsqlalchemy-pr/33.tar.gz
Distinct for subqueryload only for non-primary key columns.pr/33
-rw-r--r--lib/sqlalchemy/orm/strategies.py13
-rw-r--r--test/orm/test_subquery_relations.py24
2 files changed, 30 insertions, 7 deletions
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index dbf99a034..23e8cb623 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -767,10 +767,17 @@ class SubqueryLoader(AbstractRelationshipLoader):
if not q._from_obj and entity_mapper.isa(leftmost_mapper):
q._set_select_from([entity_mapper], False)
- # select from the identity columns of the outer
- q._set_entities(q._adapt_col_list(leftmost_attr))
+ target_cols = q._adapt_col_list(leftmost_attr)
- q._distinct = True
+ # select from the identity columns of the outer
+ q._set_entities(target_cols)
+
+ # if target_cols refer to a non-primary key or only
+ # part of a composite primary key, set the q as distinct
+ for c in target_cols:
+ if not set(target_cols).issuperset(c.table.primary_key):
+ q._distinct = True
+ break
if q._order_by is False:
q._order_by = leftmost_mapper.order_by
diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py
index d2317d2af..b3be642dc 100644
--- a/test/orm/test_subquery_relations.py
+++ b/test/orm/test_subquery_relations.py
@@ -1071,7 +1071,7 @@ class BaseRelationFromJoinedSubclassTest(_Polymorphic):
"paperwork.description AS paperwork_description, "
"paperwork.person_id AS paperwork_person_id, "
"anon_1.people_person_id AS anon_1_people_person_id "
- "FROM (SELECT DISTINCT people.person_id AS people_person_id "
+ "FROM (SELECT people.person_id AS people_person_id "
"FROM people JOIN engineers "
"ON people.person_id = engineers.engineer_id "
"WHERE engineers.primary_language = "
@@ -1119,7 +1119,7 @@ class BaseRelationFromJoinedSubclassTest(_Polymorphic):
"paperwork.description AS paperwork_description, "
"paperwork.person_id AS paperwork_person_id, "
"anon_1.people_person_id AS anon_1_people_person_id "
- "FROM (SELECT DISTINCT people.person_id AS people_person_id "
+ "FROM (SELECT people.person_id AS people_person_id "
"FROM people JOIN engineers ON people.person_id = "
"engineers.engineer_id JOIN paperwork "
"ON people.person_id = paperwork.person_id "
@@ -1537,7 +1537,7 @@ class CyclicalInheritingEagerTestTwo(fixtures.DeclarativeMappedTest,
"movie.director_id AS movie_director_id, "
"movie.title AS movie_title, "
"anon_1.director_id AS anon_1_director_id "
- "FROM (SELECT DISTINCT director.id AS director_id "
+ "FROM (SELECT director.id AS director_id "
"FROM persistent JOIN director "
"ON persistent.id = director.id) AS anon_1 "
"JOIN (persistent JOIN movie ON persistent.id = movie.id) "
@@ -1626,8 +1626,24 @@ class SubqueryloadDistinctTest(fixtures.DeclarativeMappedTest,
q2 = ctx.attributes[
('subquery', (inspect(Movie), inspect(Movie).attrs.director))
]
+ self.assert_compile(
+ q2,
+ 'SELECT director.id AS director_id, '
+ 'director.name AS director_name, '
+ 'anon_1.movie_director_id AS anon_1_movie_director_id '
+ 'FROM (SELECT DISTINCT movie.director_id AS movie_director_id '
+ 'FROM movie) AS anon_1 '
+ 'JOIN director ON anon_1.movie_director_id = director.id '
+ 'ORDER BY anon_1.movie_director_id',
+ dialect='default'
+ )
ctx2 = q2._compile_context()
-
+ result = s.execute(q2)
+ rows = result.fetchall()
+ eq_(rows, [
+ (1, 'Woody Allen', 1),
+ ])
+
q3 = ctx2.attributes[
('subquery', (inspect(Director), inspect(Director).attrs.photos))
]