Conditional requirement dependent on value of other fields in Cerberus
has been discussed many times. Usage of dependencies
doesn't meet the needs because fields can be unknown
when conditions are satisfied. Usage of oneof
was recommended but it may be too hard to work when several conditions and dependencies are met. What's the universal solution now?
可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
回答1:
Quick Answer (TL;DR)
- The "composite validation" approach allows for conditional (context-aware) validation rules.
- The python
cerberus
package supports composite validation "out of the box". - Composite validation allows for easily-human-readable rules with highly-flexible granularity on triggering conditions.
Detailed Answer
Context
- python 2.7
- cerberus validation package
Problem
- Developer JasperHuangCreator wishes to apply triggering conditions to finely-tuned validation rules.
Solution
- This approach can be accomplished with composite data validation.
- Under this use-case, composite validation simply means creating a sequential list of validation rules, such that:
- Each individual rule operates on a composite data variable
- Each individual rule specifies a "triggering condition" for when the rule applies
- Each individual rule produces one of three mutually-exclusive validation outcomes:
validation-success
,validation-fail
, orvalidation-skipped
Example
Sample documentsaadocuments = []
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
'''))
Sample validation rules
- 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]+@.*'
- The code above is a YAML formatted representation of multiple validation rules.
- The code above specifies the triggering condition through use of the
rule_vpath
name-value pair.
Rationale
- This approach can be extended to any arbitrary level of complexity.
- This approach is easily comprehensible by humans (although the jmespath syntax can be a challenge at first).
- Any arbitrarily complex set of conditions and constraints can be established using this approach.
Pitfalls
- The above example uses jmespath syntax to specify
rule_vpath
, which tells the system when to trigger specific rules, this adds a dependency on jmespath.
See also
- complete code example on github