如何用Pydantic Schema扁平化输出SQLAlchemy关联指定列
解决方案
只需要调整Pydantic序列化层的Schema定义,不需要修改ORM模型或者数据库查询逻辑,核心是通过计算字段从关联的嵌套ORM对象中提取需要的字段做扁平化输出,具体操作如下:
1. 定义扁平化的软件项输出模型
删除原有Schema中嵌套引用SoftwareName、SoftwareVersion输出模型的逻辑,新增扁平化的软件项Schema,通过属性计算从关联对象上提取name和version字段:
from pydantic import BaseModel, computed_field from typing import List class SoftwareItemOut(BaseModel): id: int # 从关联的software_name关系对象提取name字段 @computed_field @property def name(self) -> str: return self.software_name.name # 从关联的software_version关系对象提取version字段 @computed_field @property def version(self) -> str: return self.software_version.version # 开启ORM模式适配SQLAlchemy对象序列化 model_config = {"from_attributes": True}
如果你使用的是Pydantic V1版本,移除
@computed_field装饰器,将model_config替换为class Config: orm_mode = True即可,@property装饰器在V1版本下同样可以被正常序列化。
2. 修改HardwareOut模型的softwares字段类型
将HardwareOut中softwares数组的元素类型替换为上面定义的扁平化软件项模型,其余Hardware自身的字段保持原有定义不变:
class HardwareOut(BaseModel): id: int # 此处保留Hardware模型原有其他字段,例如设备编号、硬件型号、采购时间等 softwares: List[SoftwareItemOut] model_config = {"from_attributes": True}
验证说明
- 该方案不需要修改SQLAlchemy的关联关系定义,只需要保证查询Hardware数据时,通过
selectinload/joinedload预加载了softwares、softwares.software_name、softwares.software_version三层关联,避免序列化时出现N+1查询问题即可 - 调整后接口返回的结构示例如下,完全符合扁平化预期:
{ "id": 1, "device_sn": "HW-2024-0001", "softwares": [ {"id": 11, "name": "Google Chrome", "version": "126.0.6478.63"}, {"id": 27, "name": "Tencent WeChat", "version": "3.9.10.19"} ] }
内容的提问来源于stack exchange,提问作者Matheus Rodrigues Guimaraes
相关产品推荐
相关产品推荐

