EoghanM
EoghanM

Reputation: 26924

SqlAlchemy, deep eagerloading after initial load

Is it possible to initiate a deep eagerload after the initial object is loaded?

E.g., the following is great:

session.query(Foo).options(joinedload('bars.bazs')).all()

But, what if I already have foo?

foo = session.query(Foo).first()
if foo.something:
    do_nothing()
else:
    # <- would now like to eagerload 'bars.bazs'
    for bar in foo.bars:
        for baz in bar.bazs:
            # this is lazily loaded and slow

Any way to do this?

Upvotes: 1

Views: 303

Answers (1)

dieterg
dieterg

Reputation: 123

As far as I can see you are already doing what you asked for in your first example.

session.query(Foo).options(joinedload('bars.bazs')).all()

This will only load the Foo objects to start with. Only when you access the Foo.bars attribute will it load all Bar objects AND all Baz objects for all Bar objects.

If you want to eagerload all Foo, Bar and Baz objects with the initial query you would have to specify it like this:

session.query(Foo).options(joinedload('bars'), joinedload('bars.bazs')).all()

or shorter:

session.query(Foo).options(joinedload_all('bars.bazs')).all()

Documentation in the last part of this section.

To investigate how the objects get loaded from the DB when stepping through your code, you could pass echo=True to your create_engine() call.

Upvotes: 1

Related Questions