You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flask-SQLAlchemy查询返回Decimal对象无法直接jsonify的标准转换方法

解决Flask-SQLAlchemy查询Decimal结果无法jsonify的标准方法

我懂你碰到的这个问题——用聚合查询拿到的Decimal类型结果没法直接被Flask的jsonify序列化,虽然手动转int()能解决,但确实有更标准的处理方式,下面给你列几种常用方案:

1. 查询时直接转换类型(推荐单次场景)

在SQLAlchemy的查询语句里,用cast()函数把聚合结果直接转成Integer类型,这样查询返回的就是原生int,不用后续处理:

from sqlalchemy import cast, Integer
from sqlalchemy.sql import func
from sqlalchemy import or_

# 修改后的查询语句
result = ReportRecord.query.filter(
    or_(ReportRecord.spf_result == "pass", ReportRecord.dkim_result == "pass")
).with_entities(
    cast(func.sum(ReportRecord.count), Integer).label('total_passed')
).first()  # 用first()更合理,因为聚合查询只会返回一条结果

# 直接用结果即可
return jsonify({"total_passed": result.total_passed})

2. 自定义JSONEncoder(推荐全局复用场景)

如果你的项目里经常需要处理Decimal转JSON的情况,自定义一个全局的JSON编码器是最高效的方式,一劳永逸:

首先定义自定义编码器:

from flask.json import JSONEncoder
from decimal import Decimal

class DecimalJSONEncoder(JSONEncoder):
    def default(self, obj):
        # 处理Decimal类型,转成int或者float都可以,按需选择
        if isinstance(obj, Decimal):
            return int(obj)
        # 其他类型交给父类处理
        return super().default(obj)

然后在Flask应用中注册这个编码器:

from flask import Flask

app = Flask(__name__)
app.json_encoder = DecimalJSONEncoder

之后不管你查询返回的结果里有没有Decimal,直接用jsonify处理就行,它会自动帮你转换。

3. 手动处理查询结果(临时应急场景)

如果只是偶尔需要处理一次,也可以在拿到查询结果后手动转换类型,比如:

result = ReportRecord.query.filter(
    or_(ReportRecord.spf_result == "pass", ReportRecord.dkim_result == "pass")
).with_entities(func.sum(ReportRecord.count).label('total_passed')).first()

# 处理空结果的情况,避免报错
total_passed = int(result.total_passed) if result else 0

return jsonify({"total_passed": total_passed})

这里用first()代替all()是因为聚合查询只会返回一条结果,all()会返回包含单个元组的列表,处理起来多一步,用first()更简洁。

内容的提问来源于stack exchange,提问作者Ishan Khare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:27:47