summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2016-02-25 23:22:30 -0500
committerMike Bayer <mike_mp@zzzcomputing.com>2016-02-25 23:27:49 -0500
commitf8914288f012c4ef635531f09a0e13bcacacdb2a (patch)
tree1755633fd4d8e977e95f4d1fe87c39f9b60f85e4 /doc
parenteff7b4f29d2a98ef4ccd95b693c7d653eaa543eb (diff)
downloadsqlalchemy-f8914288f012c4ef635531f09a0e13bcacacdb2a.tar.gz
- An improvement to the workings of :meth:`.Query.correlate` such
that when a "polymorphic" entity is used which represents a straight join of several tables, the statement will ensure that all the tables within the join are part of what's correlating. fixes #3662
Diffstat (limited to 'doc')
-rw-r--r--doc/build/changelog/changelog_11.rst13
-rw-r--r--doc/build/changelog/migration_11.rst68
2 files changed, 80 insertions, 1 deletions
diff --git a/doc/build/changelog/changelog_11.rst b/doc/build/changelog/changelog_11.rst
index ccf99ee98..e06ae6a60 100644
--- a/doc/build/changelog/changelog_11.rst
+++ b/doc/build/changelog/changelog_11.rst
@@ -23,6 +23,19 @@
.. change::
:tags: bug, orm
+ :tickets: 3662
+
+ An improvement to the workings of :meth:`.Query.correlate` such
+ that when a "polymorphic" entity is used which represents a straight
+ join of several tables, the statement will ensure that all the
+ tables within the join are part of what's correlating.
+
+ .. seealso::
+
+ :ref:`change_3662`
+
+ .. change::
+ :tags: bug, orm
:tickets: 3431
Fixed bug which would cause an eagerly loaded many-to-one attribute
diff --git a/doc/build/changelog/migration_11.rst b/doc/build/changelog/migration_11.rst
index fb0b72de7..6c6febd08 100644
--- a/doc/build/changelog/migration_11.rst
+++ b/doc/build/changelog/migration_11.rst
@@ -16,7 +16,7 @@ What's New in SQLAlchemy 1.1?
some issues may be moved to later milestones in order to allow
for a timely release.
- Document last updated: Feburary 9, 2016
+ Document last updated: Feburary 25, 2016
Introduction
============
@@ -463,6 +463,72 @@ would have to be compared during the merge.
:ticket:`3601`
+.. _change_3662:
+
+Improvements to the Query.correlate method with polymoprhic entities
+--------------------------------------------------------------------
+
+In recent SQLAlchemy versions, the SQL generated by many forms of
+"polymorphic" queries has a more "flat" form than it used to, where
+a JOIN of several tables is no longer bundled into a subquery unconditionally.
+To accommodate this, the :meth:`.Query.correlate` method now extracts the
+individual tables from such a polymorphic selectable and ensures that all
+are part of the "correlate" for the subquery. Assuming the
+``Person/Manager/Engineer->Company`` setup from the mapping documentation,
+using with_polymorphic::
+
+ sess.query(Person.name)
+ .filter(
+ sess.query(Company.name).
+ filter(Company.company_id == Person.company_id).
+ correlate(Person).as_scalar() == "Elbonia, Inc.")
+
+The above query now produces::
+
+ SELECT people.name AS people_name
+ FROM people
+ LEFT OUTER JOIN engineers ON people.person_id = engineers.person_id
+ LEFT OUTER JOIN managers ON people.person_id = managers.person_id
+ WHERE (SELECT companies.name
+ FROM companies
+ WHERE companies.company_id = people.company_id) = ?
+
+Before the fix, the call to ``correlate(Person)`` would inadvertently
+attempt to correlate to the join of ``Person``, ``Engineer`` and ``Manager``
+as a single unit, so ``Person`` wouldn't be correlated::
+
+ -- old, incorrect query
+ SELECT people.name AS people_name
+ FROM people
+ LEFT OUTER JOIN engineers ON people.person_id = engineers.person_id
+ LEFT OUTER JOIN managers ON people.person_id = managers.person_id
+ WHERE (SELECT companies.name
+ FROM companies, people
+ WHERE companies.company_id = people.company_id) = ?
+
+Using correlated subqueries against polymorphic mappings still has some
+unpolished edges. If for example ``Person`` is polymorphically linked
+to a so-called "concrete polymorphic union" query, the above subquery
+may not correctly refer to this subquery. In all cases, a way to refer
+to the "polyorphic" entity fully is to create an :func:`.aliased` object
+from it first::
+
+ # works with all SQLAlchemy versions and all types of polymorphic
+ # aliasing.
+
+ paliased = aliased(Person)
+ sess.query(paliased.name)
+ .filter(
+ sess.query(Company.name).
+ filter(Company.company_id == paliased.company_id).
+ correlate(paliased).as_scalar() == "Elbonia, Inc.")
+
+The :func:`.aliased` construct guarantees that the "polymorphic selectable"
+is wrapped in a subquery. By referring to it explicitly in the correlated
+subquery, the polymorphic form is correctly used.
+
+:ticket:`3662`
+
.. _change_3081:
Stringify of Query will consult the Session for the correct dialect