依赖于Cerberus
中其他字段值的条件要求已经被讨论过多次。dependencies
的使用不能满足需求,因为当条件满足时,字段可以是unknown
。建议使用oneof
,但当满足几个条件和依赖性时,它可能太难工作。现在通用的解决方案是什么?
快速回答(TL;DR(
- "复合验证"方法允许条件(上下文感知(验证规则
- python
cerberus
包支持"开箱即用"的复合验证 - 复合验证允许在触发条件上具有高度灵活粒度的易于人类阅读的规则
详细答案
上下文
- python 2.7
- cerberus验证包
问题
- 开发者JasperHuangCreator希望将触发条件应用于微调的验证规则
解决方案
- 这种方法可以通过复合数据验证来实现
- 在这个用例中,复合验证只意味着创建一个验证规则的顺序列表,这样:
- 每个单独的规则都对一个复合数据变量进行操作
- 每个单独的规则都指定了适用该规则的"触发条件">
- 每个单独的规则产生三个互斥的验证结果之一:
validation-success
、validation-fail
或validation-skipped
示例
示例文档aadocuments = []
aadocuments.append(yaml.safe_load('''
person_fname: homer
person_lname: himpson
person_age: 33
prize_caption: free beer for life
prize_email: prizes@abcbooze.com
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: prizes@zzzguns.com
prize_category: firearms
'''))
验证规则示例- rule_caption: check-required-fields
rule_vpath: "@"
validation_schema:
person_fname:
type: string
required: true
person_lname:
type: string
required: true
person_age:
type: string
required: true
- rule_caption: check-age-range
rule_vpath: '@|@.person_age'
validation_schema:
person_age:
"min": 2
"max": 120
- 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格式表示
- 上面的代码通过使用
rule_vpath
名称值对来指定触发条件
基本原理
- 这种方法可以扩展到任意复杂程度
- 这种方法很容易被人类理解(尽管jmespath语法一开始可能是一个挑战(
- 使用这种方法可以建立任意复杂的条件和约束集
凹坑
- 上面的例子使用jmespath语法来指定
rule_vpath
,它告诉系统何时触发特定规则,这增加了对jmespath的依赖
另请参阅
- github上的完整代码示例