如何使用Python在DynamoDB中无类型转换存储JSON数据
在DynamoDB中原样存储JSON数据并避免类型转换
问题背景
需要在DynamoDB中以日期(YYYY-mm-dd)为键,存储对应的Python字典类型数据,但使用boto3默认存储时,数据会被转换为DynamoDB的类型标记格式(如S、N、M),查询时数字还会转为Decimal类型,不符合原样存储和使用的需求。
解决方案
方案1:将JSON数据序列化为字符串存储
直接把整个entries序列化为JSON字符串,存储为DynamoDB的字符串字段,这样存储的就是原始JSON格式,查询时再反序列化为Python字典即可。
存储代码:
import json import boto3 # 把entries序列化为JSON字符串 item = { "entries": json.dumps([ { "path": [ { "name": "test1", "count": 1 }, { "name": "test2", "count": 2 } ], "repo": "test3" } ]), "date": "2022-10-11" } dynamodb = boto3.resource('dynamodb') table = dynamodb.Table("your-table-name") table.put_item(Item=item)
查询代码:
response = table.get_item(Key={"date": "2022-10-11"}) if 'Item' in response: # 反序列化回Python字典 entries = json.loads(response['Item']['entries']) print(entries) # 此时count为整数类型,与原始数据一致
方案2:保留结构化存储并处理类型转换
如果需要保留DynamoDB的结构化存储(方便后续对嵌套字段做查询操作),可以使用boto3内置的序列化工具,在查询时将DynamoDB类型转换为原始Python类型,同时处理Decimal转整数/浮点数的问题。
查询处理代码:
import boto3 from boto3.dynamodb.types import TypeDeserializer from decimal import Decimal def convert_dynamodb_item(item): # 先将DynamoDB类型反序列化为Python基础类型 deserializer = TypeDeserializer() deserialized = {k: deserializer.deserialize(v) for k, v in item.items()} # 递归处理Decimal类型,转为整数或浮点数 def handle_decimal(obj): if isinstance(obj, Decimal): return int(obj) if obj % 1 == 0 else float(obj) elif isinstance(obj, list): return [handle_decimal(i) for i in obj] elif isinstance(obj, dict): return {k: handle_decimal(v) for k, v in obj.items()} return obj return handle_decimal(deserialized) # 查询并处理数据 dynamodb = boto3.resource('dynamodb') table = dynamodb.Table("your-table-name") response = table.get_item(Key={"date": "2022-10-12"}) if 'Item' in response: processed_item = convert_dynamodb_item(response['Item']) print(processed_item) # 输出中的count为整数类型,与原始数据一致
注意:DynamoDB底层存储本身会用类型标记(如
S代表字符串、N代表数字)来记录数据类型,所以结构化存储时无法完全避免这些标记,但通过上述反序列化处理,可以在查询后得到与原始数据一致的Python类型。
内容的提问来源于stack exchange,提问作者Ashish Sharma
相关产品推荐
相关产品推荐

