如果存在字段,则对规则进行两种不同的验证

问题描述 投票:0回答:1

我需要解析很多yml文件。我有类似的例子,在某些情况下存在一个值,因此我需要更改另一个规则的正则表达式。我找不到正确验证它的方法

yaml1:

email: [email protected]

yaml2:

email: [email protected]
contract_type: external

模式:

schema = {
  'email': {
    'required': True,
    'type': 'string',
    'regex': '^([a-zA-Z0-9_\-\.]+)@company\.com$'
  }
python validation conditional cerberus
1个回答
0
投票

快速回答(TL; DR)

  • “复合验证”方法允许条件(上下文感知)验证规则。
  • python cerberus包支持“开箱即用”的复合验证。

详细解答

Context

  • python 2.7
  • cerberus验证包
  • jmespath查询语言(使验证规则更加紧凑和可读)

Problem

  • 开发人员NamenMalkavCreator希望应用条件验证规则。
  • 条件验证规则将根据数据集中其他字段的存在或值激活。
  • 条件验证规则需要足够灵活,以便根据源数据中的任意状态或关系“即时”更改。

Solution

  • 这种方法可以通过复合数据验证来完成。
  • 在此用例下,复合验证仅表示创建验证规则的顺序列表,例如: 每个单独的规则都在复合数据变量上运行 每个单独的规则指定适用规则的“触发条件” 每个单独的规则产生三个相互排斥的验证结果之一:validation-successvalidation-failvalidation-skipped

Example

  • 以下示例假定多个YAML文档
  • 这里显示了一些示例文档
Sample documents
aadocuments = []
aadocuments.append(yaml.safe_load('''
    person_fname:         homer
    person_lname:         himpson
    person_age:           33
    prize_caption:        free beer for life
    prize_email:          [email protected]
    prize_category:       alchohol
'''))
aadocuments.append(yaml.safe_load('''
    person_fname:         helen
    person_lname:         himpson
    person_age:           16
    prize_caption:        free ammo for life
    prize_email:          [email protected]
    prize_category:       firearms
  '''))
Sample validation rule
- rule_caption:     check-underage-minor
  rule_vpath:       '[@]|[? @.person_age < `18`]'
  validation_schema:
    prize_category:
      type: string
      allowed: ['pets','toys','candy']
    prize_email:
      type:     string
      regex:    '[\w]+@.*'
  • 上面的代码是从规则列表中获取的单个验证规则的YAML格式表示。
  • 用简单的英语,这条规则规定: 如果我们在数据集中遇到记录,其中person_age小于18,那么: 断言prize_category字段存在 断言prize_category字段是字符串类型 断言prize_category的价值是petstoyscandy 断言prize_email字段存在,类型为字符串 断言prize_email字段匹配特定的正则表达式

Example outcome

  • 上面例子中helen himpson的结果将是validation-failcheck-underage-minor验证规则触发,因为person_age == 16 prize_cateogry的值为firearms,这是不允许的,因此验证失败

Rationale

  • 这种方法可以扩展到任意级别的复杂性。
  • 这种方法很容易被人理解(尽管jmespath语法可能是一个挑战)
  • 使用这种方法可以建立任何任意复杂的条件和约束。

Pitfalls

  • 上面的示例使用jmespath语法指定rule_vpath,当且仅当person_age存在且小于18时,它告诉系统触发此特定规则。这会增加对jmespath的依赖性。

See also

© www.soinside.com 2019 - 2024. All rights reserved.