扫描DynamoDB表获冗余Decimal数据,求转换为字符串格式
解决DynamoDB扫描结果中Decimal类型转换问题
我太懂这个痛点了!DynamoDB返回的数字类型默认会被boto3序列化为Decimal对象——虽然这是为了避免浮点数精度丢失,但有时候我们就是需要干净的字符串/数字格式,完全没必要带着那个Decimal()标识。
下面给你几个实用的解决方案,从简单到通用都覆盖到:
1. 手动遍历处理基础数据结构
如果你的返回数据是像示例里那样的简单字典列表,写个小函数就能快速搞定:
from decimal import Decimal # 模拟从DynamoDB获取的原始数据 raw_data = [{'year': Decimal('222'), 'title': 'aaaaaas'}, {'year': Decimal('1111'), 'title': 'dddd'}] def convert_decimal_to_str(item): converted_item = {} for key, value in item.items(): # 判断值是否为Decimal类型,是的话转成字符串 if isinstance(value, Decimal): converted_item[key] = str(value) else: converted_item[key] = value return converted_item # 批量处理整个列表 cleaned_data = [convert_decimal_to_str(item) for item in raw_data] print(cleaned_data) # 输出: [{'year': '222', 'title': 'aaaaaas'}, {'year': '1111', 'title': 'dddd'}]
要是你的数据里有嵌套的字典或列表(比如某个字段是字典,里面也藏着Decimal),可以用递归版本的函数,处理更复杂的结构:
def convert_decimals_recursively(data): if isinstance(data, list): return [convert_decimals_recursively(item) for item in data] elif isinstance(data, dict): return {key: convert_decimals_recursively(value) for key, value in data.items()} elif isinstance(data, Decimal): return str(data) # 要是确定是整数,也可以换成int(value) else: return data # 测试嵌套数据 nested_raw_data = [{'year': Decimal('222'), 'details': {'rating': Decimal('9.2'), 'release_year': Decimal('2023')}}] cleaned_nested_data = convert_decimals_recursively(nested_raw_data) print(cleaned_nested_data)
2. 扫描时直接指定序列化规则
如果你想在获取数据的环节就处理掉Decimal,可以用boto3的TypeDeserializer自定义反序列化逻辑:
import boto3 from boto3.dynamodb.types import TypeDeserializer # 用DynamoDB客户端而非资源类,便于手动控制反序列化 dynamodb_client = boto3.client('dynamodb') scan_response = dynamodb_client.scan(TableName='YourTableName') deserializer = TypeDeserializer() cleaned_data = [] for raw_item in scan_response['Items']: converted_item = {} for key, value in raw_item.items(): deserialized_val = deserializer.deserialize(value) # 检查是否为Decimal,转成字符串 if isinstance(deserialized_val, Decimal): converted_item[key] = str(deserialized_val) else: converted_item[key] = deserialized_val cleaned_data.append(converted_item)
这样扫描完成后就能直接得到你想要的格式啦~
内容的提问来源于stack exchange,提问作者Kenny Chan
相关产品推荐
相关产品推荐

