如何结合并排除'使用'默认'在架构?

时间:2018-03-09 22:35:11

标签: python validation cerberus

field_1默认情况下必须为0,但field_2不允许。我的尝试:

from cerberus import Validator

schema = {
    'value_1': {
        'type': 'integer',
        'default': 0
    },
    'value_2': {
        'type': 'integer',
        'excludes': ['value_1', ]
    }
}
v = Validator(schema)

for doc in [{}, {'value_2': 1}, {'value_2': 1, 'value_2': 1}]:
    if not v.validate(doc, schema):
        print(v.errors)
    else:
        print(v.normalized(doc))

我得到了:

{'value_1': 0}
{'value_2': ["'value_1' must not be present with 'value_2'"]}
{'value_2': ["'value_1' must not be present with 'value_2'"]}

我希望通过规范化结果{'value_1': 0, 'value_2': 1}验证第二个文档没有错误。我怎样才能达到预期的效果?

编辑更清楚地解释我的目标:
- 如果传入文档中存在value_1value_2,我想提出错误,但如果文档中不存在此密钥,则将0设置为value_1
- 我想在cerberus验证/规范化过程中进行,并希望通过更改验证模式或验证器来解决它

2 个答案:

答案 0 :(得分:0)

这只是了解您的要求。这很有效。

Doc: {}
Result: {'value_1': 0}
Doc: {'value_2': 1}
Error: {'value_2': ["'value_1' must not be present with 'value_2'"]}
Result: {'value_1': 0, 'value_2': 1}
Doc: {'value_1': 3, 'value_2': 2}
Error: {'value_2': ["'value_1' must not be present with 'value_2'"]}
Result: {'value_1': 0, 'value_2': 2}

结果:

UPDATE mysql.user SET host = '%' WHERE host != 'localhost';
FLUSH PRIVILEGES;

答案 1 :(得分:0)

快速解答(TL; DR)

  • 验证和规范化总是可以分为不同的步骤

详细答案

上下文

  • python 2.7
  • cerberus数据结构验证和标准化工具

问题

  • 方案:开发人员ElRusoDevoWoze希望将验证与数据规范化结合起来,以便为缺少的字段提供默认值。

解决方案

  • 将数据验证与数据规范化分开

理性

  • 理性;;验证和规范化可以认为是单独的过程
    • proc1 ;;区分不可接受的输入和可接受的输入
      • (垃圾与宝藏)
      • (已认证与未认证)
      • (格式正确与格式不正确)
    • proc2 ;;优化可接受输入的内容

示例

  • 以下示例创建并应用两个模式
  • 一种模式提供默认值,另一种进行验证

    import pprint
    import yaml
    from cerberus import Validator
    pass
    
    schema_vali = yaml.safe_load('''
      value_1:
        type:       integer
        excludes:   value_2
        required:   True
      value_2:
        type:       integer
        excludes:   value_1
        required:   True
    ''')
    pass
    
    schema_norm = yaml.safe_load('''
      value_1:
        default:    0
    ''')
    pass
    
    sample_docs = yaml.safe_load('''
      ¯ {}                            ## doc0
      ¯ {'value_1': 1}                ## doc1
      ¯ {'value_2': 1}                ## doc2
      ¯ {'value_1': 1, 'value_2': 1}  ## doc3
      ''')
    pass
    
    vccvali = Validator(schema_vali)
    vccnorm = Validator(schema_norm)
    pass
    
    for ijj,doc in enumerate(sample_docs):
      if vccnorm.validate(doc):
        print("{ijj} NORM-YESS! -->".format(ijj=ijj)),
        print(vccnorm.normalized(doc))
        doc = vccnorm.normalized(doc)
      if not vccvali.validate(doc):
        print("{ijj} VALI-NOPE! -->".format(ijj=ijj)),
        print(vccvali.errors)
      else:
        print("{ijj} VALI-YESS! -->".format(ijj=ijj)),
        print(vccvali.normalized(doc))
        doc = vccnorm.normalized(doc)
    pass
    

输出结果

  0 NORM-YESS! --> {'value_1': 0}
  0 VALI-YESS! --> {'value_1': 0}
  1 NORM-YESS! --> {'value_1': 1}
  1 VALI-YESS! --> {'value_1': 1}
  2 VALI-YESS! --> {'value_2': 1}
  3 VALI-NOPE! --> {'value_1': ["'value_2' must not be present with 'value_1'"], 'value_2': ["'value_1' must not be present with 'value_2'"]}