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

如何用Pydantic在JSON Schema中定义分类与子分类的依赖关系?

如何在Pydantic模型的JSON Schema中体现分类与子分类的依赖关系

问题描述

我需要在Pydantic模型的JSON Schema中明确分类与子分类的依赖对应关系,比如:

category  | subcategory
-----------------------
fruit     | apple
fruit     | orange
vegetable | cucumber
vegetable | tomato

当前的Pydantic模型如下,虽然能限制子分类的可选值,但无法在JSON Schema中体现两者的依赖关系:

class Item(pydantic.BaseModel):
    category: Literal["fruit", "vegetable"]
    subcategory: Literal["apple", "orange", "cucumber", "tomato"]

我的场景是要让UI通过JSON Schema知晓字段间的依赖,从而提供合法的分类-子分类组合选择,而不仅仅是在模型实例化时通过validator校验。

解决方案

1. JSON Schema的实现逻辑

JSON Schema支持通过oneOf关键字定义多组互斥的字段约束,每组约束对应一个分类下的合法子分类组合,UI可解析该逻辑来联动分类与子分类的可选值。

2. Pydantic的具体实现

通过定义多个子模型,结合鉴别器(discriminator),可以生成符合要求的JSON Schema:

import pydantic
from typing import Literal, Union

# 定义每个分类对应的专属子模型
class FruitItem(pydantic.BaseModel):
    category: Literal["fruit"]
    subcategory: Literal["apple", "orange"]

class VegetableItem(pydantic.BaseModel):
    category: Literal["vegetable"]
    subcategory: Literal["cucumber", "tomato"]

# 用Union结合鉴别器生成最终模型
class Item(pydantic.BaseModel):
    __root__: Union[FruitItem, VegetableItem] = pydantic.Field(
        ..., discriminator='category'
    )

# 查看生成的JSON Schema
print(Item.model_json_schema())

3. 生成的JSON Schema核心片段

生成的Schema包含oneOf数组,每个元素对应一个分类的约束逻辑,UI可直接解析这段内容实现分类与子分类的联动:

{
  "type": "object",
  "properties": {
    "__root__": {
      "oneOf": [
        {
          "type": "object",
          "properties": {
            "category": {"const": "fruit", "type": "string"},
            "subcategory": {"enum": ["apple", "orange"], "type": "string"}
          },
          "required": ["category", "subcategory"]
        },
        {
          "type": "object",
          "properties": {
            "category": {"const": "vegetable", "type": "string"},
            "subcategory": {"enum": ["cucumber", "tomato"], "type": "string"}
          },
          "required": ["category", "subcategory"]
        }
      ],
      "discriminator": {"propertyName": "category"}
    }
  },
  "required": ["__root__"]
}

4. 可选:简化写法(无需__root__)

如果不需要嵌套__root__字段,可直接将Union类型作为最终模型,生成的JSON Schema会以oneOf为顶层结构,更适合UI解析:

class Item(pydantic.BaseModel):
    pass

Item = Union[FruitItem, VegetableItem]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 01:54:51