我正在使用 Cerberus 来验证一些看起来像这样的 YAML 文件:
fleet.yml
fleet_city: "New York"
vehicles:
vehicle_1:
car:
# License plate required for car
license_plate: "ABC123"
cargo: 10
vehicle_2:
# All vehicle types can have optional remarks block
remarks:
active: true
car:
license_plate: "XYZ789"
# Cargo is optional
# Vehicle names (dict keys) are arbitrary
cool_ride:
remarks:
active: false
boat:
# Required
seaworthy: true
# not required
sails: 3
一般结构是有一些文件范围的值,例如fleet_city
,然后是一个名为vehicles
. 后者是以车辆名称为键的字典。每种车辆类型都有自己的模式,尽管它们都是字典。我想出了这个模式来正式化这个:
schema.yml
fleet_city:
type: string
vehicles:
type: dict
keysrules:
# Vehicle name constraints
type: string
regex: '[A-Za-z\d_]+'
valuesrules:
type: dict
schema:
# Optional remarks block
remarks:
type: dict
# Car schema
car:
schema:
license_plate:
type: string
required: true
cargo:
type: integer
required: false
# Boat schema
boat:
schema:
seaworthy:
type: boolean
required: true
propulsion:
type: dict
schema:
sails:
type: integer
required: false
我可以测试:
import yaml
from cerberus import Validator
with open('schema.yml') as f:
schema = yaml.safe_load(f)
v = Validator(schema)
with open('fleet.yml') as f:
fleet = yaml.safe_load(f)
print(v.validate(fleet))
print(v.errors)
哪个正确返回True
。然而,在输入中,每辆车都应该有一种类型(一个car
街区或一个boat
街区,而不是两者)。此规则未反映在上述架构中。我试着像这样添加它:
schema2.yml
fleet_city:
type: string
vehicles:
type: dict
keysrules:
# Vehicle name constraints
type: string
regex: '[A-Za-z\d_]+'
valuesrules:
type: dict
schema:
# Optional remarks block
remarks:
type: dict
oneof_schema:
# Car schema
- car:
schema:
license_plate:
type: string
required: true
cargo:
type: integer
required: false
# Boat schema
- boat:
schema:
seaworthy:
type: boolean
required: true
propulsion:
type: dict
schema:
sails:
type: integer
required: false
据我所知,我遵循了文档中给出的语法,但schema2.yml
原因是:
cerberus.schema.SchemaError: {'vehicles': [{'valuesrules': [{'schema': ['no definitions validate', {'anyof definition 0': [{'oneof': ['must be of dict type']}], 'anyof definition 1': [{'oneof': [{'schema': ['no definitions validate', 'no definitions validate', {'anyof definition 0': [{'car': ['null value not allowed'], 'schema': [{'cargo': ['unknown rule'], 'license_plate': ['unknown rule'], 'propulsion': ['unknown rule'], 'seaworthy': ['unknown rule']}], 'boat': ['null value not allowed']}], 'anyof definition 1': [{'car': ['unknown rule'], 'boat': ['unknown rule']}]}]}], 'remarks': ['unknown rule']}]}]}]}]}
这真的没有帮助。
一种解决方法是使用excludes
for car
in boat
,反之亦然,但如果我们不仅有 2 种车辆类型,而且有很多车辆类型,那么这种方法就会失败。
我的问题是什么,我schema2.yml
该如何解决?