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

Python Decimal类型不可JSON序列化 无需手动转换的修复方案

修复DynamoDB返回数据JSON序列化Decimal类型报错问题

报错原因

boto3查询DynamoDB返回的数值类型会统一转换为Python的Decimal类型,Python标准json模块默认未实现该类型的序列化逻辑,因此触发类型错误。

无侵入修复方案(无需手动修改嵌套Dict)

方案1:自定义JSON编码器(推荐,无额外依赖)

自定义继承自json.JSONEncoder的序列化类,重写类型匹配逻辑,json.dumps会自动递归遍历整个嵌套结构执行转换,无需手动处理多层级数据。

import json
from decimal import Decimal

class DecimalEncoder(json.JSONEncoder):
    def default(self, o):
        if isinstance(o, Decimal):
            # 可根据业务需求选择对应转换逻辑
            # 选项1:自动判断转换为int或float
            if o.as_integer_ratio()[1] == 1:
                return int(o)
            return float(o)
            # 选项2:转换为字符串,保留完全精度
            # return str(o)
        return super(DecimalEncoder, self).default(o)

调用时仅需传入cls参数即可:

result = json.dumps(table_scan, cls=DecimalEncoder)

不同转换逻辑的适用场景:

  • 自动转int/float:适合绝大多数业务场景,返回的数值类型和原始写入类型一致,前端无需额外处理
  • 转字符串:适合金融、计费等对数值精度要求极高的场景,避免浮点精度丢失,前端接收后可自行转换为数值类型

方案2:使用boto3内置类型转换工具

也可以直接调用boto3自带的DynamoDB数据反序列化工具完成转换:

from boto3.dynamodb.types import TypeDeserializer
import json

deserializer = TypeDeserializer()
# 转换整个DynamoDB返回的嵌套结构
formatted_data = deserializer.deserialize({'M': table_scan})
result = json.dumps(formatted_data)

API网关返回适配

返回给AWS API网关时需要符合指定结构,示例如下:

return {
    "statusCode": 200,
    "headers": {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    "body": json.dumps(table_scan, cls=DecimalEncoder)
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 00:06:04