SQLAlchemy: Load cascading relationships in fewest number of queries (N+1 problem)

Viewed 190

In reading through SQLAlchemy's documentation, I'm struggling to find a solution to this problem:

I have a very basic database model, with a Parent entity that has a one-to-many relationship with a Child entity, which in turn has a one-to-many relationship with a Grandchild entity. These relationships are defined using SQLAlchemy's default lazy-load behavior, because 99% of the time it makes sense for the loading of these relationships to be deferred.

However, in that other 1% of the time, an expensive operation needs to happen on a Parent instance which requires loading all of its children and grandchildren. I would like to do this in as few queries as possible, ideally only 2:

SELECT * FROM child WHERE parent_id=<>
SELECT * FROM grandchild WHERE child_id IN (<>)

I know how to do this when I'm building a Query statement from scratch, by chaining together multiple selectinload functions to Query.options:

parent = session.query(Parent).options(
    selectinload(Parent.children).selectinload(Child.grandchildren)
).get(parent_id)

However, if I already have the Parent instance loaded into memory, how can I trigger the loading of its Parent.children relationship & Child.grandchildren relationships in the same way as the above query? Sort of like a way to temporarily override the relationship's defined loader strategy, or a way to specify the Query.options(...) method above, but without creating a Query statement, because my starting point is an already-loaded Parent instance, not a parent_id.

0 Answers
Related