Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sqlalchemy joinedload: syntax to load multiple relationships more than 1 degree separated from query table?

Is there a more concise syntax for using sqlalchemy joinedload to eager load items from more than one table that only relates to the query table by way of another intermediate table (or is there an alternative load syntax that is better for what I am trying to do)?

For example, using the familiar data structure of questions, answers, etc, is there a more succinct way than the example below to query a question, eager load the related answers, and eager load both the answer comments and the answer votes (assume, for this example, that both of these answer related items are contained in separate tables)?

from sqlalchemy.orm import joinedload

result = session.query(Question).\
    options(
       joinedload(Question.answers).
       joinedload(Answer.comments)
       ).\
    options(
       joinedload(Question.answers).
       joinedload(Answer.votes)
       ).\
    filter(Question.id == '1').\
    first()

I could not find any examples of loading multiple tables by way of an intermediate table at Relationship Loading Techniques (or anywhere else for that matter). I did attempt to include multiple sub-relationships inside a single joinedload like...

result = session.query(Question).\
    options(joinedload(Question.answers, Answer.comments, Answer.votes)).\
    filter(Question.id == '1').\
    first()

...but that approach, not surprisingly, just chains the joins.

like image 690
benvc Avatar asked Aug 22 '18 18:08

benvc


People also ask

How do you create a many to many relationship in sqlalchemy?

Python Flask and SQLAlchemy ORM Many to Many relationship between two tables is achieved by adding an association table such that it has two foreign keys - one from each table's primary key.

What is Joinedload sqlalchemy?

join() is used to alter the results of a query, joinedload() goes through great lengths to not alter the results of the query, and instead hide the effects of the rendered join to only allow for related objects to be present.

What does all () do in sqlalchemy?

all() method. The Query object, when asked to return full entities, will deduplicate entries based on primary key, meaning if the same primary key value would appear in the results more than once, only one object of that primary key would be present.


1 Answers

You want Load.options()

Then your code would be something like:

result = session.query(Question).\
    options(
        joinedload(Question.answers).\
        options(
            joinedload(Answer.comments),
            joinedload(Answer.votes)
            )
        ).\
    filter(Question.id == '1').\
    first()
like image 101
Christophe Biocca Avatar answered Oct 10 '22 06:10

Christophe Biocca