python - Psycopg2 在查询中使用 CASE 语句时无法调整类型“BinaryExpression”
问题描述
我有下一个查询:
sub_qry = self.session.query(
TableA.currency,
func.sum(func.case([(TableB.status_id == EStatus.REPORTED.value, 1)], else_=0)).label('status')
) \
.filter_by(period_id=period_id) \
.outerjoin(TableB) \
.group_by(TableA.currency) \
.subquery()
result = self.session.query(func.count(sub_qry.c.status)).filter(sub_qry.c.status != 1).first()
但它因错误而崩溃:
(psycopg2.ProgrammingError) can't adapt type 'BinaryExpression'
[SQL: SELECT count(anon_1.status) AS count_1
FROM (SELECT table_a.currency AS currency, sum(case(%(case_1)s)) AS status
FROM table_a LEFT OUTER JOIN table_b ON table_a.id = table_b.table_a_id
WHERE table_a.period_id = %(period_id_1)s GROUP BY table_a.currency) AS anon_1
WHERE anon_1.status != %(status_1)s
LIMIT %(param_1)s]
[parameters: {'case_1': [(<sqlalchemy.sql.elements.BinaryExpression object at 0x0000022FC0F42700>, 1)], 'period_id_1': 4, 'status_1': 1, 'param_1': 1}]
(Background on this error at: http://sqlalche.me/e/13/f405)
我究竟做错了什么?我在网上查了很多样品,似乎一切都很好。
添加:
有效的 SQL 版本:
select count(r.status)
from (
select a.currency, SUM(CASE WHEN b.status_id = 2 THEN 1 else 0 END) as status from table_b b
right outer join table_a a on a.id = b.table_a_id
where a.period_id = 4
group a.currency
) r
where r.status != 1
解决方案
我发现了我的错误:调用sqlalchemy.func.case()
而不是sqlalchemy.case()
.
这一点很重要!SQLAlchemy只会在第二种情况下生成正确的 SQL 查询。
PS这是一个微不足道的错误,但如果有人遇到同样的问题,我决定将其保存在这里。
推荐阅读
- r - 对半个数据集的列进行随机化
- python - 尽管尝试了各种解决方案,但 Jupyter Notebook 未上传 CSV 文件
- python-3.x - 如何获取包含无法通过 requests.get 获取的标签的数据?
- jquery - 更改没有键名的json值
- firebase - vue 项目中的 Firebase 功能不会部署到谷歌云
- javascript - 在获取之前执行下一个代码块我该如何解决
- caffe - 如何将 caffe 的 BatchNorm 重量转换为 pytorch BathNorm?
- ruby-on-rails - 更新到 Rails 4.0,突然传递了两个参数
- facebook-graph-api - 是否可以通过 facebook graph api 或任何其他资源获取所有共享特定帖子的用户 ID?
- javascript - 通过迭代获取生成器的返回值