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

如何将嵌套Pydantic模型序列化为扁平JSON?附疑问

解决方案与疑问解答

一、实现扁平化序列化(无需重复定义字段)

方案1:自定义扁平化函数处理Pydantic模型输出

直接在序列化阶段对model_dump()的结果进行递归扁平化,自动给嵌套字段添加父字段前缀,无需修改原模型定义:

from pydantic import BaseModel

class StaffMember(BaseModel):
    fname: str
    lname: str
    id: int

class CandidateResponse(BaseModel):
    id: int
    content: str
    created_by: StaffMember
    updated_by: StaffMember

def flatten_model_data(model_instance, parent_key="", sep="_"):
    flattened = {}
    for key, value in model_instance.model_dump().items():
        new_key = f"{parent_key}{sep}{key}" if parent_key else key
        if isinstance(value, dict):
            # 递归处理嵌套字典
            flattened.update(flatten_model_data(value, new_key, sep))
        else:
            flattened[new_key] = value
    return flattened

# 示例使用
staff = StaffMember(fname="Alice", lname="Smith", id=2)
candidate = CandidateResponse(id=50, content="面试通过", created_by=staff, updated_by=staff)
flat_json = flatten_model_data(candidate)

输出的扁平结构示例:

{
    "id": 50,
    "content": "面试通过",
    "created_by_fname": "Alice",
    "created_by_lname": "Smith",
    "created_by_id": 2,
    "updated_by_fname": "Alice",
    "updated_by_lname": "Smith",
    "updated_by_id": 2
}

方案2:SQLAlchemy查询阶段直接扁平化

如果数据来自SQLAlchemy查询,可以在查询时通过label给关联字段添加前缀,直接返回扁平结果,再映射到Pydantic模型(适合不需要保留嵌套模型的场景):

from sqlalchemy import select

# 假设SQLAlchemy模型为Staff和Candidate
query = select(
    Candidate.id,
    Candidate.content,
    Staff.fname.label("created_by_fname"),
    Staff.lname.label("created_by_lname"),
    Staff.id.label("created_by_id"),
    # 同理处理updated_by关联的Staff字段
).join(Staff, Candidate.created_by_id == Staff.id)

# 查询结果直接是扁平结构,可直接传入扁平版Pydantic模型

二、疑问解答

1. 返回扁平对象给API消费者是否恰当?

取决于具体场景:

  • 适合场景:如果消费者是前端、移动端等简单客户端,扁平结构无需深层嵌套取值,降低前端处理复杂度;如果已经和消费者约定了扁平格式,按约定实现即可。
  • 需要谨慎的场景:如果是面向复杂系统集成的API,嵌套结构更能清晰体现数据的关联语义,扩展性更强(比如StaffMember新增字段时,嵌套结构只需在子对象中扩展,不会污染顶层字段)。
    建议先和API消费者对齐需求,评估双方的维护和使用成本后再决定。

2. 是否有其他更合适的实现方案?

除上述方案外,还可以:

  • 利用Pydantic v2+的@computed_field:逐个定义扁平字段,复用嵌套模型的属性(适合仅需部分字段扁平化的场景,但需要手动定义每个字段)。
  • 自定义Pydantic模型的json()方法:重写序列化逻辑,在模型内部实现扁平化,对外提供统一的序列化入口。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 06:16:17