如何用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
相关产品推荐
相关产品推荐

