1

我正在使用 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']}]}]}]}]}

这真的没有帮助。

一种解决方法是使用excludesfor carin boat,反之亦然,但如果我们不仅有 2 种车辆类型,而且有很多车辆类型,那么这种方法就会失败。

我的问题是什么,我schema2.yml该如何解决?

4

0 回答 0