Python Lambda读取DynamoDB返回APIGateway时Decimal类型无法JSON序列化问题
解决Python AWS Lambda中DynamoDB Decimal类型JSON序列化报错问题
报错原因
DynamoDB的所有数值类型查询返回后默认会被转换为Python的Decimal类型,而Python标准库的json模块原生不支持该类型的序列化,因此会触发你遇到的TypeError。
你之前使用的TypeSerializer/TypeDeserializer是用于和DynamoDB原生带类型标记的AttributeValue格式互转的工具,你已经通过boto3 resource接口拿到了解析后的普通字典,输入格式不符合Deserializer的要求,所以不会生效。
解决方案
方案1:自定义json序列化处理器(无需额外依赖,最常用)
给json.dumps添加default参数,自定义Decimal类型的转换逻辑,可适配所有Decimal字段的序列化需求:
import json from decimal import Decimal def handle_decimal(obj): if isinstance(obj, Decimal): # 整数类型的Decimal转int,适合年份、计数等整数场景 if obj.as_tuple().exponent >= 0: return int(obj) # 带小数的Decimal可按需转float或者字符串(转字符串可完全避免精度丢失) return float(obj) raise TypeError(f"Object of type {obj.__class__.__name__} is not JSON serializable") def lambda_handler(event, context): # 这里省略你的DynamoDB查询逻辑 dynamodbTableQueryData = {'year': Decimal('2015'), 'info': {'rating': Decimal('0'), 'plot': 'Nothing happens at all.'}, 'title': 'The Big New Movie'} return { 'statusCode': 200, 'body': json.dumps(dynamodbTableQueryData, default=handle_decimal) }
方案2:手动转换单个字段(仅适用于少量明确字段的场景)
如果你只需要返回特定的数值字段,直接手动转换类型即可,比如你之前报错的year字段可以这么改:
return { 'statusCode': 200, 'body': json.dumps(int(dynamodbTableQueryData['year'])) }
方案3:使用支持Decimal序列化的第三方json库
如果你的Lambda运行环境可以引入第三方依赖,simplejson原生支持Decimal类型序列化,使用更简洁:
- 先将simplejson打包到Lambda层或部署包中
- 代码修改为:
import simplejson as json def lambda_handler(event, context): # 省略DynamoDB查询逻辑 return { 'statusCode': 200, 'body': json.dumps(dynamodbTableQueryData, use_decimal=True) }
内容的提问来源于stack exchange,提问作者Stéphane GRILLON
相关产品推荐
相关产品推荐

