首页 > 解决方案 > 使用 pydantic 生成验证根列表和映射的 json 模式

问题描述

我正在尝试编写一个模式,该模式可用于验证两种不同的需求格式,一个 v1 曾经是根级别的列表,另一个是使用映射的较新格式:

# requirements.yml v1
- {}  # the mapping inside being a RoleModel
...
# requirements.yml v2
roles:
  - {}  # the mapping inside being a RoleModel
  ...
collections:
  - {}  # the mapping inside being a CollectionModel
  ...

我能够为这两个版本中的任何一个生成不同的模式,但我不知道如何将这两个版本组合成一个模式。

出于实际原因,我不能使用不同的模式,因为文件名相同并且 Ansible 加载两者,因此在打开文件之前无法确定模式。

对于 v2 fommat,我在https://github.com/ansible-community/ansible-lint/blob/schemas/src/ansiblelint/schemas/requirements.py有一个实现

我确实了解到,为了在根级别验证列表,我需要执行类似https://github.com/ansible-community/ansible-lint/blob/schemas/src/ansiblelint/schemas/playbook.py#L35之类的操作:

top_level_schema = schema([RoleModel], title='Requiremetns v1 Schema')

如何将两者结合在一个模式中,一个涵盖上面列出的两个示例的模式?

标签: pythonjsonschemapydantic

解决方案


对于 JSON Schema,您希望使用具有一组模式值的应用程序。

根据您向我展示的代码,剧本模式实际上并没有生成有用的模式(只有定义,没有实际验证)。

根据 pydantic 的文档,您似乎想使用 Union 类型。

https://pydantic-docs.helpmanual.io/usage/schema/#json-schema-types

Union[str, int]
anyOf
{"anyOf": [{"type": "string"}, {"type": "integer"}]}

同样的方法可能适用于您定义的类,但我无法测试。

如果没有,我建议你在他们的 github repo 上提出问题。虽然,我已经找到了类似的功能请求:https ://github.com/samuelcolvin/pydantic/issues/2036


推荐阅读