SQLAlchemy-Utils聚合属性:如何在聚合前过滤生成聚合字段?
实现仅统计活跃评论数量的修改方案
完全可以实现,只需修改comment_count的聚合逻辑,添加对active=True的过滤条件,以下是两种常用实现方式:
方式一:通过装饰器参数直接过滤
在@aggregated装饰器中添加filter参数,指定仅统计活跃评论:
from sqlalchemy_utils import aggregated import sqlalchemy as sa class Thread(Base): __tablename__ = 'thread' id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.Unicode(255)) @aggregated('comments', sa.Column(sa.Integer), filter=Comment.active == True) def comment_count(self): return sa.func.count('1') comments = sa.orm.relationship( 'Comment', backref='thread' ) class Comment(Base): __tablename__ = 'comment' id = sa.Column(sa.Integer, primary_key=True) content = sa.Column(sa.UnicodeText) thread_id = sa.Column(sa.Integer, sa.ForeignKey(Thread.id)) active = sa.Column(sa.Boolean)
方式二:在聚合函数中使用条件计数
通过case语句实现条件计数,适合更复杂的判断场景:
from sqlalchemy_utils import aggregated import sqlalchemy as sa class Thread(Base): __tablename__ = 'thread' id = sa.Column(sa.Integer, primary_key=True) name = sa.Column(sa.Unicode(255)) @aggregated('comments', sa.Column(sa.Integer)) def comment_count(self): # 仅对active=True的评论进行计数 return sa.func.count(sa.case((Comment.active == True, 1))) comments = sa.orm.relationship( 'Comment', backref='thread' ) class Comment(Base): __tablename__ = 'comment' id = sa.Column(sa.Integer, primary_key=True) content = sa.Column(sa.UnicodeText) thread_id = sa.Column(sa.Integer, sa.ForeignKey(Thread.id)) active = sa.Column(sa.Boolean)
两种方式的区别:
- 方式一的过滤逻辑会体现在SQL的WHERE子句中,直接筛选出符合条件的评论后再计数
- 方式二通过条件判断在聚合时忽略非活跃评论,逻辑更灵活,支持多条件组合
内容的提问来源于stack exchange,提问作者Howard S
相关产品推荐
相关产品推荐

