简体   繁体   English

SQLAlchemy 仅查找包含特定子代的父代

[英]SQLAlchemy find only parents that contain specific children

I have the following many-to-many models:我有以下多对多模型:


class Association(db.Model):
    parent_id = db.Column(db.Integer, db.ForeignKey(
        'parent.id'), primary_key=True)
    child_id = db.Column(db.Integer, db.ForeignKey(
        'child.id'), primary_key=True)
    child = db.relationship("Child", back_populates="parents")
    parent = db.relationship("Parent", back_populates="children")


class Parent(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    children = db.relationship("Association", back_populates='parent', 
                               lazy='dynamic', cascade="save-update, merge, delete, delete-orphan")

class Child(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    parents = db.relationship("Association", back_populates='child', 
                              lazy='dynamic', cascade="save-update, merge, delete, delete-orphan")

How can I get all parents that have the exact children ids in a list (Example: [5,6]) and no additional ids?如何获取所有在列表中具有确切子 ID(例如:[5,6])且没有其他 ID 的父母?

If you have determined the children ids in a subquery, you can make a left join from association table to this subquery and check that the count is correct:如果您已确定子查询中的子 ID,则可以从关联表到该子查询进行左连接并检查计数是否正确:

from sqlalchemy import func, and_

Values = [1 ,3]
childcount = len(Values)
childsquery = db.session.query(Child).filter(Child.id.in_(Values)).subquery()             
resultparents = db.session.query(Association.parent_id).outerjoin(childsquery).group_by(Association.parent_id).having(and_(func.count(Association.parent_id) == childcount, func.count(childsquery.c.id) ==  childcount))

Remark: I think your model needs to be corrected:备注:我认为您的模型需要更正:

class Parent(db.Model):
   id = db.Column(db.Integer, primary_key=True)
   children = db.relationship("Association", back_populates='parent', 
            lazy='dynamic', cascade="save-update, merge, delete, delete-orphan")

class Child(db.Model):
   id = db.Column(db.Integer, primary_key=True)
   parents = db.relationship("Association", back_populates='child', 
                          lazy='dynamic', cascade="save-update, merge, delete, delete orphan")

I ended up solving it using the following code:我最终使用以下代码解决了它:

ids = [c1, c2, c3]
q1 = Parent.query.filter(Parent.children.any(
Association.child_id == c1)).filter(Parent.children.any(Association.child_id == c2))
.filter(Parent.children.any(Association.child_id == c3))
.filter(~Parent.children.any(Association.child_id.notin_(ids)))
.all()

But I am pretty sure there must be better ways to do this.但我很确定必须有更好的方法来做到这一点。

If you are using postgresql, the following should work:如果您使用的是 postgresql,以下应该可以工作:

from sqlalchemy.dialects.postgresql import array, array_agg
ids = [c1, c2, c3]
q1 = Parent.query.join(Child)
            .group_by(Parent)
            .having(
                array_agg(Child.id).contains(array(ids)), 
                count(Child.id) == len(ids)
            )

Most probably there will be alternatives for other databases as well.很可能还会有其他数据库的替代品。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SQLAlchemy 查询所有孩子匹配过滤器的父母 - SQLAlchemy query parents with ALL children matching a filter sqlalchemy 按孩子月/年计算唯一父母 - sqlalchemy count unique parents by children month/year 在 SQLAlchemy 中有效地找到没有孩子的父母 - In SQLAlchemy efficiently find chidless parents SQLAlchemy在子代中查找所有重复项 - SQLAlchemy find all duplicates in children 查找仅包含特定字符的字符串中的单词 - Find words in strings which contain specific characters only GQL-选择所有不在特定孩子中的父母 - GQL - Select all parents where specific child is not in children 如何将 sqlalchemy 查询过滤到所有符合 Flask 表格条件的父母(不带孩子)和所有父母 - How to filter an sqlalchemy query to all Parents w/o Children, and all Parents, who fall under conditions in a Flask Form 段落中的嵌套跨度不会包裹在子节点上,只会包裹在父节点上 - Nested spans in a paragraph will not wrap on children nodes, only on parents 通过sqlalchemy关系通过backref属性获取父母子女会导致不必要的刷新 - Getting a parents children through a backref attribute via sqlalchemy relationship causes unnecessary flush 推荐人,推荐人,父母和子女 - Referrers, Referents, Parents and Children
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM