Sqlalchemy:获取 child 计数而不读取所有 children

Sqlalchemy: Get child count without reading all the children

这是我的 Parent 和 Child 类:

class Parent(Base):
    id = Column(...)
    ...

    children = relationship("Child", backref="parent", lazy="select")

class Child(Base):
    id = Column(...)
    parent_id = Column(...)
    active = Column(Boolean(), ...)

childrenParent 的加载技术背后的原因是 Parent 是惰性的,因为可以有大量的 children 与 parent 关联。

现在,我想获得 parent 的活动 children 的数量作为 hybrid-property。以下是我尝试这样做的方法:

class Parent(Base):
    ...

    @hybrid_property
    def active_count(self):
        return len([child for child in self.children if child.active])

    @active_count.expression
    def active_count(cls):
        return (
            select(func.count(Child.id))
            .where(Child.parent_id == cls.id)
            .where(Child.active == True)
        )

但是这个方法的问题是,当我调用 parent.active_count 时,它会触发一个查询以获取所有 children.

如何在不阅读整个 children 的情况下仅获取(活动 children 的计数)?

我认为您没有必要在 active_count hybrid_property 定义中迭代子项。这应该适合你:

class Parent(Base):
    ...
    children = relationship("Child", backref="parent", lazy="dynamic")

    @hybrid_property
    def active_count(self):
        return self.children.filter_by(active=True).with_entities(func.count('*')).scalar()
        # or 
        # return self.children.filter_by(active=True).count()
        # but it would have worse performance