summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2013-04-18 10:40:28 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2013-04-18 10:40:28 -0400
commita2c52f1e07259f05006c1303fba000dfb3b9fd64 (patch)
tree2efc1545ae855abce982e1430023d638356d83af
parent3772b968318058a5cbbd98c33a369be72e0de435 (diff)
downloadsqlalchemy-a2c52f1e07259f05006c1303fba000dfb3b9fd64.tar.gz
- additional test + correction for [ticket:2699]
-rw-r--r--lib/sqlalchemy/orm/strategies.py9
-rw-r--r--test/orm/test_subquery_relations.py53
2 files changed, 57 insertions, 5 deletions
diff --git a/lib/sqlalchemy/orm/strategies.py b/lib/sqlalchemy/orm/strategies.py
index eece47207..a5c2c7fdf 100644
--- a/lib/sqlalchemy/orm/strategies.py
+++ b/lib/sqlalchemy/orm/strategies.py
@@ -802,11 +802,12 @@ class SubqueryLoader(AbstractRelationshipLoader):
# to look only for significant columns
q = orig_query._clone()
- # TODO: why does polymporphic etc. require hardcoding
- # into _adapt_col_list ? Does query.add_columns(...) work
- # with polymorphic loading ?
- if entity_mapper.isa(leftmost_mapper):
+ # set a real "from" if not present, as this is more
+ # accurate than just going off of the column expression
+ if not q._from_obj and entity_mapper.isa(leftmost_mapper):
q._set_select_from(entity_mapper.mapped_table)
+
+ # select from the identity columns of the outer
q._set_entities(q._adapt_col_list(leftmost_attr))
if q._order_by is False:
diff --git a/test/orm/test_subquery_relations.py b/test/orm/test_subquery_relations.py
index 3de363a9c..fd4289f6e 100644
--- a/test/orm/test_subquery_relations.py
+++ b/test/orm/test_subquery_relations.py
@@ -1037,7 +1037,7 @@ class BaseRelationFromJoinedSubclassTest(fixtures.MappedTest):
sess.add_all([e1, e2])
sess.flush()
- def test_correct_subquery(self):
+ def test_correct_subquery_nofrom(self):
sess = create_session()
# use Person.paperwork here just to give the least
# amount of context
@@ -1084,6 +1084,57 @@ class BaseRelationFromJoinedSubclassTest(fixtures.MappedTest):
)
)
+ def test_correct_subquery_existingfrom(self):
+ sess = create_session()
+ # use Person.paperwork here just to give the least
+ # amount of context
+ q = sess.query(Engineer).\
+ filter(Engineer.primary_language == 'java').\
+ join(Engineer.paperwork).\
+ filter(Paperwork.description == "tps report #2").\
+ options(subqueryload(Person.paperwork))
+ def go():
+ eq_(q.one().paperwork,
+ [Paperwork(description="tps report #1"),
+ Paperwork(description="tps report #2")],
+
+ )
+ self.assert_sql_execution(
+ testing.db,
+ go,
+ CompiledSQL(
+ "SELECT people.person_id AS people_person_id, "
+ "people.name AS people_name, people.type AS people_type, "
+ "engineers.engineer_id AS engineers_engineer_id, "
+ "engineers.primary_language AS engineers_primary_language "
+ "FROM people JOIN engineers "
+ "ON people.person_id = engineers.engineer_id "
+ "JOIN paperwork ON people.person_id = paperwork.person_id "
+ "WHERE engineers.primary_language = :primary_language_1 "
+ "AND paperwork.description = :description_1",
+ {"primary_language_1": "java",
+ "description_1": "tps report #2"}
+ ),
+ CompiledSQL(
+ "SELECT paperwork.paperwork_id AS paperwork_paperwork_id, "
+ "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 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 "
+ "WHERE engineers.primary_language = :primary_language_1 AND "
+ "paperwork.description = :description_1) AS anon_1 "
+ "JOIN paperwork ON anon_1.people_person_id = "
+ "paperwork.person_id "
+ "ORDER BY anon_1.people_person_id, paperwork.paperwork_id",
+ {"primary_language_1": "java",
+ "description_1": "tps report #2"}
+ )
+ )
+
+
class SelfReferentialTest(fixtures.MappedTest):