Python 使用条件计算行数的混合表达式

Python 使用条件计算行数的混合表达式,python,sqlalchemy,Python,Sqlalchemy,我有4张桌子: 现在我需要一种方法(可能是混合属性)来告诉我在一个带有notes''的Cebola中有多少个检查表 我补充说: Cebola类(基本): @杂化性 def注释数(自我): 返回len([c在self.checklist中表示c,如果是c.notes]) @评论数量(cls) def注释数(cls): ??? 我在中发现了一个类似的问题,但我的示例有点复杂 下面应该是您的入门指南: class Cebola(Base): __tablename__ = 'cebolas

我有4张桌子:

现在我需要一种方法(可能是混合属性)来告诉我在一个带有
notes''
的Cebola中有多少个检查表

我补充说:

Cebola类(基本):
@杂化性
def注释数(自我):
返回len([c在self.checklist中表示c,如果是c.notes])
@评论数量(cls)
def注释数(cls):
???

我在中发现了一个类似的问题,但我的示例有点复杂

下面应该是您的入门指南:

class Cebola(Base):
    __tablename__ = 'cebolas'
    id = Column(Integer, primary_key=True, autoincrement=True)

    @hybrid_property
    def number_of_comments(self):
        # return len([c for c in self.checklists if c.notes])
        # @NOTE:1: below will prevent error for those that do not have `notes` column
        # @NOTE:2: in any case this may issue a lot of SQL statements to load all subclasses of checklists relationship, so is not really efficient
        return len([c for c in self.checklists
                    if hasattr(c, 'notes') and c.notes])

    @number_of_comments.expression
    def number_of_comments(cls):
        from sqlalchemy import select
        ce, cl, cla, clb = [
            _.__table__ for _ in (Cebola, Checklist, ChecklistA, ChecklistB)]
        s = (
            select([func.count(cl.c.id).label("number_of_comments")])
            .select_from(cl.outerjoin(cla).outerjoin(clb))
            .where(or_(cla.c.notes != None, clb.c.notes != None))
            .where(cl.c.cebola_id == cls.id)
            .correlate(cls)
            .as_scalar()
        )
        return s
查询中的用法:

q = session.query(Cebola, Cebola.number_of_comments)
for cebola, number_of_comments in q.all():
    print(cebola, number_of_comments)

您希望如何处理
检查表
没有
注释
属性的通用实例?@van它们可以忽略,谢谢您的回答。我只是怀疑session在混合表达式中的用法。如果还没有对象的实例,我如何获得它?你是对的,在混合表达式中使用
session
不是正确的做法。我刚刚用
和_polymorphic
做了一个简单的查询来完成这项工作(这让所有这些
左外连接都很好)。但是您可以直接使用表达式构造相同的表达式。只使用表达式更新答案,而不使用查询实例,这将生成相同的查询。根据数据库和表的数量,您甚至可以将
where
子句移动到
join
条件的一部分,因为在某些数据库上可能更快。谢谢!谁会想到这是如此简单;)
q = session.query(Cebola, Cebola.number_of_comments)
for cebola, number_of_comments in q.all():
    print(cebola, number_of_comments)