pydantic 模型,其字段具有依赖的允许值

问题描述 投票:0回答:1

我有一个 pydantic 模型,其中包含具有依赖允许值的字段,我希望在 JSON 模式中正确表示这些字段。将其视为类别/子类别关系,例如:

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

我的 pydantic 模型看起来像这样:

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

这是正确的,因为它限制允许的子类别字段不包括

puzzles
或任何其他意外的子类别,但此结构没有正确指定 JSON 模式中类别及其允许的子类别之间的依赖关系。是否可以在 JSON Schema 中指定这种关系?假设这是可能的,用 pydantic 实现这一点的合适方法是什么?

我知道 pydantic 验证器,但这仅在模型实例化时检查传入的数据。在我的用例中,我希望能够允许用户从 UI 中选择有效的类别和子类别,因此 UI 需要通过 JSON 架构了解这些不同字段之间的依赖关系(理想情况下)。

jsonschema pydantic python-jsonschema
1个回答
0
投票

您可以通过创建两个单独的模型来实现此目的,这些模型使用

Literal
s 实现此依赖关系。

让我们创建模型:

from pydantic import BaseModel
from typing import Literal


class Item(BaseModel):
    category: str
    subcategory: str


class Fruit(Item):
    category: Literal['fruit']
    subcategory: Literal['apple', 'orange']


class Vegetable(Item):
    category: Literal['vegetable']
    subcategory: Literal['cucumber', 'tomato']


class Foo(BaseModel):
    item: Fruit | Vegetable

这里的关键是我们也有一个类似的模型

Foo
,其中字段类型是所有可能类型的联合。然后 Pydantic 将尝试找到合适的匹配。由于我们使用了
Literal
,因此需要满足依赖关系。

这是一个测试:

Foo(item ={'category': 'fruit', 'subcategory': 'apple'})
# Foo(item=Fruit(category='fruit', subcategory='apple'))

Foo(item={'category': 'fruit', 'subcategory': 'tomato'})
# ValidationError: 2 validation errors for Foo
# item.Fruit.subcategory
#   Input should be 'apple' or 'orange' [type=literal_error, input_value='tomato', input_type=str]
#     For further information visit https://errors.pydantic.dev/2.6/v/literal_error
# item.Vegetable.category
#   Input should be 'vegetable' [type=literal_error, input_value='fruit', input_type=str]
#     For further information visit https://errors.pydantic.dev/2.6/v/literal_error
© www.soinside.com 2019 - 2024. All rights reserved.