如何在Python中向AWS DynamoDB存储原生格式字典?
Problem Description
I'm trying to store the dictionary {"amount":"2.9","date":[]} into AWS DynamoDB. In Haskell, I can use code like formattedInfo = avS .~ info $ attributeValue from Network.AWS.DynamoDB to get the desired native-style format, but when I use the following Python code with boto3:
formatted_data = {'amount': str(data['amount']), 'date': data['date']} if 'Item' in item_response: table.update_item( Key={ 's3ObjectKey': s3_key }, UpdateExpression='SET kiData = :val1', ExpressionAttributeValues={ ':val1': formatted_data } ) else: table.put_item( Item={ 's3ObjectKey': s3_key, 'kiData': formatted_data } )
The stored result ends up being this AttributeValue-wrapped structure:
{ "amount" : { "S" : "2.9" }, "date" : { "L" : [ ] }}
This works, but it's not as convenient as the clean native format {"amount":"2.9","date":[]}. How can I achieve storing the native format directly?
Solution
Got it, let's break this down—you have two solid options depending on your use case:
Option 1: Store as a JSON String (for raw native format visibility)
If you want the stored value to look exactly like the clean {"amount":"2.9","date":[]} in the DynamoDB console or when retrieved as a raw string, convert your dictionary to a JSON string before storing. This is perfect if you just need to save and fetch the full object without interacting with its nested fields in DynamoDB.
Here's the adjusted code:
import json # Build your data dictionary as before formatted_data = {'amount': str(data['amount']), 'date': data['date']} # Convert it to a JSON string json_data = json.dumps(formatted_data) if 'Item' in item_response: table.update_item( Key={'s3ObjectKey': s3_key}, UpdateExpression='SET kiData = :val1', ExpressionAttributeValues={':val1': json_data} ) else: table.put_item( Item={'s3ObjectKey': s3_key, 'kiData': json_data} )
When you retrieve this later, just parse it back into a Python dictionary with json.loads(item['kiData']) to work with it natively.
Option 2: Use boto3's Resource Mode for Automatic Type Conversion
If you need to work with nested fields (like querying by amount or updating date directly), storing as a DynamoDB Map type is the right call. The wrapped { "S": "2.9" } structure you see is just DynamoDB's internal storage format—boto3's Resource API will automatically convert this back to clean native Python types when you fetch the item.
For example, when you retrieve the item:
response = table.get_item(Key={'s3ObjectKey': s3_key}) item = response.get('Item') print(item['kiData']) # This outputs: {'amount': '2.9', 'date': []}
Your original code is actually working correctly—you're just seeing the raw internal format in the DynamoDB console. The native format you want is automatically restored when you fetch the data via the Resource API.
If you're using the boto3 Client API instead of the Resource API, you can manually convert the AttributeValue structure with TypeDeserializer:
from boto3.dynamodb.types import TypeDeserializer deserializer = TypeDeserializer() native_ki_data = {k: deserializer.deserialize(v) for k, v in item['kiData'].items()}
But switching to the Resource API is simpler and more intuitive for most day-to-day use cases.
内容的提问来源于stack exchange,提问作者Chuck Aguilar

