from_self() should cancel out eager loads when it calls query.statement

Issue #1276 resolved
Mike Bayer repo owner created an issue

this will take a new conditional in EagerLoader.setup_query.

from sqlalchemy import Column, Integer, String, create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class Foo(Base):
    __tablename__ = 'foo'
    id = Column(Integer, primary_key=True)
    data = Column(String)

    def __repr__(self):
        return "Foo(%r)" % self.data

engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)

session = sessionmaker(engine)()

session.add_all([   Foo(data='f1'),
    Foo(data='f2'),
    Foo(data='f3'),
    Foo(data='f4'),
    Foo(data='f5'),
](
))

session.commit()

from sqlalchemy import ForeignKey
from sqlalchemy.orm import relation, backref

class Bar(Base):
    __tablename__ = 'bar'
    id = Column(Integer, primary_key=True)
    data = Column(String)
    foo_id = Column(Integer, ForeignKey('foo.id'))
    foo = relation(Foo, backref=backref('bars', collection_class=set))

    def __repr__(self):
        return "Bar(%r)" % self.data

Base.metadata.create_all(engine)

f3 = session.query(Foo).filter(Foo.data=='f3').one()
f5 = session.query(Foo).filter(Foo.data=='f5').one()

session.add_all([   Bar(data='b1', foo=f3),
    Bar(data='b2', foo=f5),
    Bar(data='b3', foo=f5),
    Bar(data='b4', foo=f5),
    ](
))
session.commit()

# only issues one subquery, one LEFT OUTER JOIN
for f in session.query(Foo).order_by(Foo.data.desc()).\
             limit(3).from_self().options(eagerload(Foo.bars)).\
            order_by(Foo.data):
    print f, [for b in f.bars](b)

# delivers same results, but uses *two* subqueries, 
# two LEFT OUTER JOINs, the inner one unused
for f in session.query(Foo).order_by(Foo.data.desc()).\
             limit(3).options(eagerload(Foo.bars)).from_self().\
            order_by(Foo.data):
    print f, [for b in f.bars](b)

Comments (2)

  1. Log in to comment