如何用Pydantic TypeAdapter将字典列表解析为带关联的Mail模型列表?
解决Pydantic模型解析与双向关联绑定问题
核心问题说明
原始字典数据仅包含Mail和Attachment的基础字段,但模型定义了双向关联字段(Mail.mailbox、Attachment.mail),同时需要用TypeAdapter替代已弃用的parse_obj_as完成解析。
1. TypeAdapter的基础用法
Pydantic v2中TypeAdapter是parse_obj_as的替代方案,针对特定类型创建适配器后即可完成数据解析:
- 针对目标类型(如
List[Mail])创建TypeAdapter实例 - 调用
validate_python方法传入原始字典数据,直接得到模型实例列表
2. 处理双向关联绑定
由于原始数据不含关联字段,直接解析会触发验证错误,需分两步操作:
- 将模型中的关联字段设为可选(带默认值
None),确保解析通过 - 解析完成后手动遍历实例,绑定双向关联关系
完整实现代码
from typing import List, Optional from pydantic import BaseModel, TypeAdapter class Mailbox: def get_mails(self) -> List['Mail']: return getattr(self, '_mails', []) class Mail(BaseModel): id: int attachments: List['Attachment'] mailbox: Optional[Mailbox] = None # 设为可选字段,适配原始数据结构 class Attachment(BaseModel): filename: str size: int mail: Optional[Mail] = None # 设为可选字段,适配原始数据结构 # 解决模型前向引用问题 Mail.model_rebuild() Attachment.model_rebuild() # 原始邮件数据 raw_mail_data = [ { "id": 1, "attachments": [ {"filename": "some.txt", "size": 128}, {"filename": "some2.txt", "size": 256} ] }, { "id": 2, "attachments": [ {"filename": "some.txt", "size": 64} ] } ] # 用TypeAdapter解析为Mail实例列表 mail_adapter = TypeAdapter(List[Mail]) mail_list = mail_adapter.validate_python(raw_mail_data) # 创建Mailbox实例并绑定关联 mailbox = Mailbox() mailbox._mails = mail_list # 绑定所有双向关联 for mail in mail_list: mail.mailbox = mailbox for attachment in mail.attachments: attachment.mail = mail # 验证关联效果 print(f"Mail 1的Mailbox实例: {mail_list[0].mailbox}") print(f"Attachment 1对应的Mail实例: {mail_list[0].attachments[0].mail}")
内容的提问来源于stack exchange,提问作者Wapper
相关产品推荐
相关产品推荐

