Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
676 views
in Technique[技术] by (71.8m points)

python - SQLAlchemy - list of parents with count of filtered children

I'm using SQLAlchemy to try and retrieve a full list of parents, and a count of a filtered list of their children. I have a feeling it needs subqueries, but I'm not too hot on it.

For example, here are parents and children models:

class Parent(db.Model):
__tablename__ = "parent"

id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))



class Child(db.Model):
__tablename__ = "child"

id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey("parent.id")
child_type = db.Column(db.String(1))
name = db.Column(db.String(32))

parent = db.relationship("Parent", backref='children')

Let's say we have the following entries in here:

PARENT_1 - 3 children (type A, B, B)

PARENT_2 - 1 child (type A)

PARENT_3 - no children

I want a query that prints a list of ALL parents, and the numbers of children that are type B. So it would spit out:

PARENT_1, 2
PARENT_2, 0
PARENT_3, 0

This is what I was attempting so far, which works for when there are B type children, but won't include the parents without any.

counts = db.session.query(
   Parent.id,
   db.func.count(Child.id)
).join(
   Child, Child.parent_id==Parent.id
).filter(
   Child.child_type=='B'
).group_by(
   Parent.id
)

I tried making the filter or_(Child.child_type=='B', not_(Parent.children.any(Child.child_type=='s'))) but then it gives the total child count instead of the filtered one.

I hope this is clear. Where would I go from here?

Edit:

I think I've found a way to do it with subqueries, but if there are no children matching, it returns None instead of 0, so I presume there's still a better way... regardless:

subquery = db.session.query(
   Parent.id.label('parent_id'),
   db.func.count(Child.id).label('child_count')
).join(
   Child, Child.parent_id==Parent.id
).filter(
   Child.child_type=='B'
).group_by(
   Parent.id
).subquery()

counts = db.session.query(
   Parent.id,
   subquery.c.child_count
 ).outerjoin(
   subquery,
   Parent.id==subquery.c.parent_id
 )
question from:https://stackoverflow.com/questions/65925699/sqlalchemy-list-of-parents-with-count-of-filtered-children

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...