eagerload creates a redundant join when the loaded relation is already joined

Issue #863 resolved
Former user created an issue

(original reporter: ants) Given an Parent has many Child type of schema, there should be a way to query Child, eagerload its parent and filter by the parents attributes without joining the parent table twice. By doing

session.query(Child).options(eagerload('parent')).join('parent').filter_by(name='xyz')

we get SQL like:

SELECT child.id AS child_id, child.parent_id AS child_parent_id, child.name AS child_name, parent_1.id AS parent_1_id, parent_1.name AS parent_1_name
FROM child JOIN parent ON parent.id = child.parent_id LEFT OUTER JOIN parent AS parent_1 ON parent_1.id = child.parent_id
WHERE parent.name = ? ORDER BY child.oid, parent_1.oid

It would be preferrable to have this:

SELECT child.id AS child_id, child.parent_id AS child_parent_id, child.name AS child_name, parent.id AS parent_id, parent.name AS parent_name
FROM child JOIN parent ON parent.id = child.parent_id 
WHERE parent.name = ? ORDER BY child.oid, parent.oid

That is, reuse the regular joins that follow exclusively to-one relation paths for eagerloads.

Comments (3)

  1. Mike Bayer repo owner
    • changed milestone to 0.5.0

    I love that you're actually paying attention to these. this one would might be very tricky, as eagerloading would have to carefully look at what the query criterion already includes and perform various second-guessing about it, if it is indeed the same join criterion as what the eager load would use, if theres some aliasing it needs to be aware of, etc. ...the rules for this to work in all cases may be pretty involved. im not inclined to rush into this one too quickly right now :).

  2. Mike Bayer repo owner

    This use case can be exactly met right now, in both the current 0.4 as well as 0.5, by using the contains_eager() option instead of the eagerload() option. Its an optimization (or even a change the collections actually loaded) that the end user can control completely.

  3. Log in to comment