Reputation: 751
I am new to SQLAlchemy so bear a bit with me if the question is not properly articulated.
But I have a particular problem I would like to solve. Let say we have a parent, child, and toy table. Where we have a m2m relationship between family-parent, parent-child and child-toy.
Now if we would like to gather all family in which a toy is present ( a child can be part of the parent family and grandparents family) we would do:
select * from family where parent_id in ( select parent_id from parent where child_id in (select child_id from child where toy_id in (1,2)))
And I would like to convert this to a SQLAlchemy
or flask_sqlalchemy
query.
One way I know of is to do something like :
Toy.query.filter(Toy.id.in_((1, 2))).all()
Or in pure SQLAlchemy:
session.query(Toy).filter(Toy.id.in_((1, 2))).all()
Then get the output put it into a list comprehension and use the list as the input of another where in.
But this feels very inefficient as the query would be evaluated on each filter/list comprehension creation.
Is there any way to have this query in a single flask_sqlalchemy
or just pure SQLAlchemy
command, in such a way that it can be evaluated only once?
Thank you in advance for your help!
Upvotes: 2
Views: 326
Reputation: 1627
You can actually create a filter_list, and then execute the query at once as you described
filter_list = list()
filter_list.append(Child.toy_id.in_([1,2]))
filter_list.append(Child.toy_id.in_([4,5])) # some other condition...
# more conditions here...
result = session.query(Child).filter(*filter_list).all()
the *filter_list syntax automatically applies all the conditions you appended to the filter_list
Upvotes: 3
Reputation: 746
try use subquery:
ch = session.query(Child.child_id).filter(Child.toy_id.in_([1,2])).subquery('ch')
p = session.query(Parent.parent_id).filter(Parent.child_id.in_(ch)).subquery('p')
result = session.query(Family).filter(Family.parent_id.in_(p)).all()
Upvotes: 3