diff options
author | Alexander Koval <kovalidis@gmail.com> | 2013-10-11 23:49:26 +0300 |
---|---|---|
committer | Alexander Koval <kovalidis@gmail.com> | 2013-10-11 23:49:26 +0300 |
commit | 9e61d9eb51eb38da95b7df330b16db0fb4b0b1b4 (patch) | |
tree | c9a47980906a73d87d7238eda1a7ba47b55f052b | |
parent | a84af718858d63e123814e4c9683c8ce2ab11dee (diff) | |
download | sqlalchemy-pr/33.tar.gz |
Distinct for subqueryload only for non-primary key columns.pr/33
-rw-r--r-- | lib/sqlalchemy/orm/strategies.py | 13 | ||||
-rw-r--r-- | test/orm/test_subquery_relations.py | 24 |
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)) ] |