SQLAlchemy中Decimal类型求和始终为0?求助解决
问题分析与解决
核心问题
求和返回0的原因有两个:
- 错误引用列:用字符串
"coeff"作为func.sum参数时,SQLAlchemy会将其视为字符串常量而非子查询中的数值列,数据库解析时会把该字符串转成0,最终求和结果为0。 - 分组逻辑错误:原
round_uniqueness按Play.round_id分组却选择Play.play_id,不符合SQL聚合规则(非聚合列需出现在GROUP BY中),还会导致后续关联逻辑混乱。
修正步骤
1. 修正回合独特性系数计算逻辑
正确计算每个回合的独特性系数,以round_id作为分组键:
# 筛选答对的记录 scored_plays = Play.query.join(Round).join(User).filter(Round.outcome == Play.guess) # 计算每个回合的独特性系数:1/该回合答对的用户数 round_uniqueness = scored_plays.with_entities( Play.round_id, (1.0 / func.count(User.user_id)).label("coeff") ).group_by(Play.round_id)
2. 正确关联并求和
将子查询命名后,明确引用其列对象进行求和:
# 转换为子查询并命名 round_uniq_subq = round_uniqueness.subquery() # 关联子查询,按user_id求和coeff user_coeff_sum = scored_plays.join( round_uniq_subq, Play.round_id == round_uniq_subq.c.round_id # 明确关联条件 ).with_entities( Play.user_id, func.sum(round_uniq_subq.c.coeff) # 引用子查询的coeff列 ).group_by(Play.user_id) # 查看结果 user_coeff_sum.all()
可选:确保数值类型一致性
若仍存在类型问题,可通过func.cast强制转换系数类型:
round_uniqueness = scored_plays.with_entities( Play.round_id, func.cast(1.0 / func.count(User.user_id), db.Float).label("coeff") ).group_by(Play.round_id)
内容的提问来源于stack exchange,提问作者Milan C.
相关产品推荐
相关产品推荐

