Python jsonschema定义抽象数据类型时错误异常及实现方案咨询
问题1 解答
你定义的JSON Schema完全符合官方规范,使用enum限制key属性取值的写法不存在语法错误。
错误提示不符合预期的原因是oneOf的默认校验逻辑:oneOf要求实例必须刚好匹配分支列表中的一个分支,你给出的测试数据{"key": "bar"}同时不满足两个分支的要求(第一个分支要求key值为foo,第二个分支要求必填baritem字段),jsonschema默认会按分支顺序上报第一个匹配失败的错误,因此你看到的是第一个分支的enum校验失败提示,而非第二个分支缺必填字段的提示。
问题2 解答
要实现「根据key属性取值匹配对应校验分支,精准返回对应分支的校验错误」的需求,推荐使用JSON Schema Draft 07及以上版本支持的if/then/else关键字实现,错误提示比oneOf友好很多,示例如下:
import jsonschema from jsonschema import Draft7Validator schema = { "type": "object", "additionalProperties": False, "required": ["key"], "properties": { "key": {"type": "string", "enum": ["foo", "bar"]} }, "if": {"properties": {"key": {"const": "foo"}}}, "then": { "additionalProperties": False, "properties": { "key": {"const": "foo"} } }, "else": { "if": {"properties": {"key": {"const": "bar"}}}, "then": { "additionalProperties": False, "required": ["baritem"], "properties": { "key": {"const": "bar"}, "baritem": {"type": "string"} } } } } try: Draft7Validator(schema).validate({"key": "bar"}) except jsonschema.ValidationError as e: print(e)
运行后返回的错误提示符合预期:
'baritem' is a required property Failed validating 'required' in schema['else']['then']: {'additionalProperties': False, 'properties': {'baritem': {'type': 'string'}, 'key': {'const': 'bar'}}, 'required': ['baritem']} On instance: {'key': 'bar'}
如果分支较多,可以改用allOf包裹多组if/then的结构,扩展性更强:
schema = { "type": "object", "additionalProperties": False, "required": ["key"], "properties": { "key": {"type": "string", "enum": ["foo", "bar", "baz"]} }, "allOf": [ { "if": {"properties": {"key": {"const": "foo"}}}, "then": { "properties": {"key": {"const": "foo"}}, "additionalProperties": False } }, { "if": {"properties": {"key": {"const": "bar"}}}, "then": { "required": ["baritem"], "properties": { "key": {"const": "bar"}, "baritem": {"type": "string"} }, "additionalProperties": False } }, { "if": {"properties": {"key": {"const": "baz"}}}, "then": { "required": ["bazitem", "bazcount"], "properties": { "key": {"const": "baz"}, "bazitem": {"type": "string"}, "bazcount": {"type": "integer"} }, "additionalProperties": False } } ] }
内容的提问来源于stack exchange,提问作者David Froger
相关产品推荐
相关产品推荐

