使用 Pydantic V2 实现带区分器的联合类型

DDD
发布: 2025-08-08 15:26:17
原创
362人浏览过

使用 pydantic v2 实现带区分器的联合类型

在 Pydantic V2 中,处理联合类型(Union Type)时,如果不同的模型具有相似的结构,Pydantic 可能会因为缺少足够的信息而无法正确地解析 JSON 数据。例如,当两个模型都包含一个列表类型的 items 字段,且没有其他明确的区分标志时,Pydantic 可能会错误地将数据解析为其中一个模型。为了解决这个问题,可以使用区分器(Discriminator)来明确指定用于区分不同模型的字段。

区分器(Discriminator)的作用

区分器是一个字段,它的值可以用来确定应该使用联合类型中的哪个模型来解析数据。通过在 Pydantic 模型中指定区分器,可以确保数据被正确地解析为预期的类型。

如何使用区分器

以下是一个示例,展示了如何在 Pydantic V2 中使用区分器:

import datetime
from typing import Annotated, Union, List, Literal

import pydantic
from pydantic import Field


class MealsService(pydantic.BaseModel):

    class MealItem(pydantic.BaseModel):
        course: str
        name: str
        quantity: int
        unitPrice: float | None

    type: Literal['meals'] = "meals"
    items: list[MealItem]
    time: datetime.time | None


class CanapesService(pydantic.BaseModel):

    class CanapeItem(pydantic.BaseModel):
        name: str
        quantity: int
        unitPrice: float | None

    type: Literal['canapes'] = "canapes"
    items: list[CanapeItem]
    time: datetime.time | None


Services = Annotated[Union[MealsService, CanapesService], Field(discriminator='type')]


class Event(pydantic.BaseModel):
    services: List[Services]

# 示例 JSON 数据
data = {
    "services": [
        {
            "type": "canapes",
            "items": [],
            "time": None
        }
    ]
}

# 解析 JSON 数据
event = Event(**data)

# 打印解析结果
print(event)
登录后复制

代码解释:

  1. 定义模型: 首先定义了 MealsService 和 CanapesService 两个 Pydantic 模型,它们都包含 type 字段,用于区分不同的服务类型。注意type字段使用了Literal['meals']和Literal['canapes'],确保该字段的值只能是预定义的值。
  2. 使用 Annotated 和 Field: 使用 Annotated 将 Union[MealsService, CanapesService] 包装起来,并通过 Field(discriminator='type') 指定 type 字段作为区分器。这意味着 Pydantic 将根据 type 字段的值来决定使用哪个模型来解析数据。
  3. 创建 Event 模型: 创建 Event 模型,其中 services 字段是一个包含 Services 类型的列表。
  4. 解析 JSON 数据: 使用 Event(**data) 将 JSON 数据解析为 Event 模型的实例。Pydantic 会根据 type 字段的值正确地将数据解析为 CanapesService 类型的实例。

注意事项:

  • 确保区分器字段的值在不同的模型中是唯一的。
  • 区分器字段必须存在于所有联合类型中的模型中。
  • 区分器字段的类型必须是可区分的,例如字符串或枚举。

总结:

通过使用区分器,可以解决 Pydantic 在解析联合类型时可能出现的歧义问题,确保数据被正确地解析为预期的模型。这种方法在处理具有相似结构的多个模型时非常有用,可以提高数据解析的准确性和可靠性。 在定义 Pydantic 模型时,合理利用 Literal 类型,可以进一步约束字段的取值范围,增强模型的健壮性。

以上就是使用 Pydantic V2 实现带区分器的联合类型的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
相关标签:
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2025 //m.sbmmt.com/ All Rights Reserved | php.cn | 湘ICP备2023035733号