Python Cerberus校验JSON数组Schema报SchemaError问题排查
问题原因
你的Schema写法存在3处核心错误,本质是混淆了Cerberus校验库的规则语法和标准JSON Schema的语法,才触发了对应的报错:
- 类型关键字错误:Cerberus里列表类型的标识是
list,不是JSON Schema用的array;Cerberus里也没有properties这个校验规则,字典类型的字段规则需要定义在schema字段下。 - 列表规则关键字错误:Cerberus中给列表所有元素定义统一校验规则用
schema关键字;items是用来按位置匹配列表元素规则的(比如分别定义列表第1、2、3位元素的校验规则),不是用来定义全局统一元素规则的。 - Schema传参位置错误:当你把schema传给
Validator构造函数时,Cerberus默认会把schema当做字典结构的校验规则——也就是schema的顶层key会被识别为待校验字典的字段名,所以它会把你写的type、items都当成待校验字典的字段,才会抛出'type': ['must be of dict type']的错误(它以为你要校验字典里名为type的字段,要求该字段是字典类型)。如果待校验的顶层值不是字典(比如你这里是列表),需要把schema作为参数传入validate()方法,而不是构造函数。
修正后的可运行代码
import requests from cerberus import Validator def test_get_booking_ids_correct_schema(): # 完全符合Cerberus语法的schema schema = { "type": "list", "schema": { # 定义列表所有元素的统一校验规则 "type": "dict", # 声明列表元素是字典类型 "schema": { # 定义字典内的字段规则,替代JSON Schema的properties "bookingid": { "type": "integer" } } } } response = requests.get("https://restful-booker.herokuapp.com/booking") response_body = response.json() v = Validator() # 顶层非字典类型校验时,schema传给validate方法,不要传给Validator构造函数 is_valid = v.validate(response_body, schema) assert is_valid == True
你之前写的单对象校验代码能正常运行,是因为待校验值本身就是字典,schema的顶层keyorigin正好对应字典的字段名,完全符合Cerberus构造函数接收schema的默认逻辑,所以不会报错。
内容的提问来源于stack exchange,提问作者adrnrtkvski
相关产品推荐
相关产品推荐

