You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Pydantic嵌套模型转为字典写入DynamoDB并保留原始嵌套结构?

问题:Pydantic嵌套模型写入DynamoDB时保留原始嵌套字典结构

我用Pydantic定义了嵌套模型,读取数据后打印的结构如下:

{
   "Name": "jhon",
   "Address": {
      "HouseNumber": 20,
      "current": true,
      "street": "easy street"
   }
}

但写入DynamoDB后,Address字段被保存为带类型标识的结构:

Name | Address
jhon | {"HouseNumber":{"N":"20"},"current": {"BOOL": true}, ...}

我希望Address字段直接保存为{"HouseNumber": "20", "current": true, "street": "easy street"}这样的原始嵌套字典结构,请问该怎么做?

我的写入代码:

import boto3
import json

dynamo_resource = boto3.Session().resource('dynamodb', region_name='us-west-2')
person_table = dynamo_resource.Table('person')

with person_table.batch_writer() as batch:
    for i in person_list:
        # 转换为JSON再解析回字典
        json_string = i.model_dump_json()
        record = json.loads(json_string)
        batch.put_item(Item=record)

我的Pydantic模型定义:

from pydantic import BaseModel
from typing import Optional

class Address(BaseModel):
    HouseNumber: int
    current: bool
    street: str

class Person(BaseModel):
    Name: str
    Address: Optional[Address]

解决方案

要让Address字段以原始嵌套字典格式保存到DynamoDB,有两种可行方案:

方案1:将Address序列化为JSON字符串存储

直接把Address字段转为JSON字符串,存入DynamoDB的字符串类型字段,读取时再反序列化回字典,这种方式简单直接,适合不需要对子字段做查询的场景:

修改写入代码:

import boto3

dynamo_resource = boto3.Session().resource('dynamodb', region_name='us-west-2')
person_table = dynamo_resource.Table('person')

with person_table.batch_writer() as batch:
    for i in person_list:
        record = i.model_dump()
        # 将Address对象转为JSON字符串
        if record.get('Address'):
            record['Address'] = record['Address'].model_dump_json()
        batch.put_item(Item=record)

读取时还原Address结构:

from pydantic import TypeAdapter

response = person_table.get_item(Key={'Name': 'jhon'})
item = response['Item']
# 将JSON字符串转回Address对象或字典
item['Address'] = TypeAdapter(Address).json_loads(item['Address'])

方案2:使用boto3客户端构造原生Map类型

如果需要基于Address的子字段做查询、排序等操作,可将Address存储为DynamoDB原生的Map类型,通过boto3客户端手动构造字段类型:

import boto3

dynamo_client = boto3.Session().client('dynamodb', region_name='us-west-2')

for i in person_list:
    record = i.model_dump()
    # 构造符合DynamoDB格式的Item
    dynamodb_item = {
        'Name': {'S': record['Name']},
    }
    if record.get('Address'):
        dynamodb_item['Address'] = {
            'M': {
                'HouseNumber': {'N': str(record['Address']['HouseNumber'])},
                'current': {'BOOL': record['Address']['current']},
                'street': {'S': record['Address']['street']}
            }
        }
    dynamo_client.put_item(TableName='person', Item=dynamodb_item)

这种方式下,DynamoDB控制台会将Address显示为正常嵌套字典;通过boto3 resource读取时,会自动转换为Python原生字典,无需手动处理类型标识。

内容的提问来源于stack exchange,提问作者kishi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 21:35:01