繁体   English   中英

Pydantic:使用文字验证有区别的联合

[英]Pydantic: Validate discriminated union with literals

我正在尝试使用Literal与 Pydantic 创建一个有区别的联合。 有关于 Job 资源的事件,我想通过event_name来区分它们。 对于JobPublishedEvents ,我想确保存在一些extra_field

class GenericJobEvent(BaseModel):
    event_name: str
    id: int


class JobPublishedEvent(GenericJobEvent):
    event_name: Literal['job.published']
    extra_field: str


class Wrapper(BaseModel):
    wrapped: Union[JobPublishedEvent, GenericJobEvent]

print(type(Wrapper(wrapped={'event_name': 'some.event', 'id': 1}).wrapped))  # GenericJobEvent
print(type(Wrapper(wrapped={'event_name': 'job.published', 'id': 1, 'extra_field': 'extra'}).wrapped))  # JobPublishedEvent
print(type(Wrapper(wrapped={'event_name': 'job.published', 'id': 1}).wrapped))  # GenericJobEvent

前两种情况的行为符合预期,对于第三种情况,我想要一个验证错误,因为文字匹配,但架构没有实现。 不过,我明白为什么回退到 GenericJobEvent 是有效的。

有人知道如何实现这一目标吗?

问题是由于JobPublishedEvent失败,而GenericJobEvent没有。 想想看, event_name属性是一个字符串, id是一个int。 一切都匹配。

因此,您可以做的是验证GenericJobEvent中的event_name并拒绝事件名称job.published

您可以按照文档中的说明对其进行验证

@validator('event_name')
    def event_name_filter(cls, v):
        if 'job.published' == v:
            raise ValueError('GenericJobEvent cannot have event_name equal to job.published')
        return v.title()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM