diff options
| author | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-02-25 23:22:30 -0500 |
|---|---|---|
| committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2016-02-25 23:27:49 -0500 |
| commit | f8914288f012c4ef635531f09a0e13bcacacdb2a (patch) | |
| tree | 1755633fd4d8e977e95f4d1fe87c39f9b60f85e4 /doc | |
| parent | eff7b4f29d2a98ef4ccd95b693c7d653eaa543eb (diff) | |
| download | sqlalchemy-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.rst | 13 | ||||
| -rw-r--r-- | doc/build/changelog/migration_11.rst | 68 |
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 |
