Reputation: 98
So currently I have two classes Foo
and Bar
where
class Foo(db.Model):
...
bars = db.relationship('Bar', backref='foo', lazy='dynamic')
...
Here, a Foo
can have many Bar
's.
How can I query Foo
such that I can filter by the number of Bar
's? Something like Foo.query.filter(Foo.bars.count() == x).first()
Would there be another way to do this other than keeping a count variable?
Upvotes: 1
Views: 664
Reputation: 55600
This SQL query would be one way of doing it (assuming x = 2):
SELECT parent.id, COUNT(child.tid) AS num_bars
FROM parent
JOIN child ON parent.id = child.tid
GROUP BY parent.id
HAVING COUNT(child.tid) = 2;
This would translate to (sqlalchemy):
import sqlalchemy as sa
x = 2
q = (session.query(Foo, sa.func.count(Bar.foo_id).label('num_bars'))
.join(Bar)
.group_by(Foo.id)
.having(sa.literal_column('num_bars') == x)
.from_self(Foo))
the flask-sqlalchemy equivalent would probably be
q = (db.session.query(Foo, sa.func.count(Bar.foo_id).label('num_bars'))
.join(Bar)
.group_by(Foo.id)
.having(sa.literal_column('num_bars') >= x)
.from_self(Foo))
Another way to do it would be to use a subquery:
SELECT parent.id
FROM parent
WHERE (SELECT COUNT(1)
FROM child
WHERE child.tid = parent.id
) = 2
which would look like this using SQLAlchemy:
subq = (session.query(sa.func.count(Bar.foo_id))
.filter(Bar.foo_id == Foo.id)
.scalar_subquery())
q = session.query(Foo).filter(subq == 2)
Upvotes: 1