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(), ...)
children
或 Parent
的加载技术背后的原因是 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
这是我的 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(), ...)
children
或 Parent
的加载技术背后的原因是 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