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
相关产品推荐
相关产品推荐

