【问题标题】:Using 'case' in a select query sqlalchemy throwing exception在选择查询 sqlalchemy 中使用“案例”引发异常
【发布时间】:2017-04-24 08:34:10
【问题描述】:

我正在尝试将这个 sql 查询构造成 sqlalchemy:

select distinct
    processed_by_user_uuid,
    sum(case when audited_result_uuid = PASSED_RESULT_UUID then 1 else 0 end) as "passed",
    sum(case when audited_result_uuid <> PASSED_RESULT_UUID then 1 else 0 end) as "failed",
    count(distinct processed_using) as "total audits"
from audit
where
    audited_at is not null
    and processed_at > [start_time]
    and processed_at < [end_time]
group by 1

我的尝试:

query = Session.query(audit_table).with_entities(
    audit_table.c.processed_by_user_uuid,
    func.sum(
        case([audit_table.c.audited_result_uuid == PASSED_RESULT_UUID, 1], else_=0)
    ).label('passed'),
    func.sum(
        case([audit_table.c.audited_result_uuid != PASSED_RESULT_UUID, 1], else_=0)
    ).label('failed'),
    func.count(distinct(audit_table.c.processed_using)).label('total audits')
).filter(
    audit_table.c.audited_at is not None,
    audit_table.c.processed_at > start_time,
    audit_table.c.processed_at < end_time
).group_by(
    1
)

当我尝试这个时,我得到了异常:

NotImplementedError: Operator 'getitem' is not supported on this expression

通过一些挖掘,它对这条线不满意:

func.sum(
    case([audit_table.c.audited_result_uuid == PASSED_RESULT_UUID, 1], else_=0)
).label('passed')

【问题讨论】:

    标签: python postgresql sqlalchemy


    【解决方案1】:

    您没有正确使用case(...) - 您需要将您的条件放在(condition, value) 的元组中,以便:

    case([audit_table.c.audited_result_uuid == PASSED_RESULT_UUID, 1], else_=0)
    

    变成:

    case([(audit_table.c.audited_result_uuid == PASSED_RESULT_UUID, 1)], else_=0)
    

    这同样适用于另一个 case 语句。


    此外,您的过滤条件audit_table.c.audited_at is not None 不会导致您尝试构建的查询。此表达式将评估为 Trueboolean 值,因此将生成 truthy WHERE 子句,例如 WHERE 1=1(或什么都没有)。
    相反,您应该使用audit_table.c.audited_at != None。 PEP-8 检查会报错,但这是它应该与 sqlalchemy 一起使用的方式。

    【讨论】:

      猜你喜欢
      • 2021-04-30
      • 2014-07-29
      • 2021-08-12
      • 1970-01-01
      • 2017-03-20
      • 2017-08-06
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      相关资源
      最近更新 更多