如何在架构中将 'excludes' 与 'default' 结合起来?
How is possible to combine 'excludes' with 'default' in schema?
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_1
和 value_2
,我想引发错误,但如果文档中不存在此键,则将 0
设置为 value_1
。
- 我想在 cerberus validation/normalization 过程中进行,并想通过更改验证模式或验证器
来解决它
这只是在了解您的要求后。这行得通。
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': 2, 'value_1': 3}]:
print('Doc: {}'.format(doc))
n_doc = {}
if not v.validate(doc, schema):
print('Error: {}'.format(v.errors))
n_doc = v.normalized(doc)
n_doc.update(v.normalized({}))
else:
n_doc = v.normalized(doc)
print('Result: {}'.format(n_doc))
结果:
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}
快速回答 (TL;DR)
- 验证和标准化总是可以分成不同的步骤
详细解答
上下文
- python 2.7
- cerberus 数据结构验证和规范化工具
问题
- 场景:开发人员 ElRusoDevoWoze 希望将验证与数据规范化相结合,以便为缺失的字段提供默认值。
解决方案
- 将数据验证与数据规范化分开
理由
- 理由;;验证和规范化可以被认为是独立的过程
- proc1;;区分不可接受的输入和可接受的输入
- (垃圾vs宝)
- (已验证与未验证)
- (良构与非良构)
- 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'"]}
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_1
和 value_2
,我想引发错误,但如果文档中不存在此键,则将 0
设置为 value_1
。
- 我想在 cerberus validation/normalization 过程中进行,并想通过更改验证模式或验证器
这只是在了解您的要求后。这行得通。
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': 2, 'value_1': 3}]:
print('Doc: {}'.format(doc))
n_doc = {}
if not v.validate(doc, schema):
print('Error: {}'.format(v.errors))
n_doc = v.normalized(doc)
n_doc.update(v.normalized({}))
else:
n_doc = v.normalized(doc)
print('Result: {}'.format(n_doc))
结果:
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}
快速回答 (TL;DR)
- 验证和标准化总是可以分成不同的步骤
详细解答
上下文
- python 2.7
- cerberus 数据结构验证和规范化工具
问题
- 场景:开发人员 ElRusoDevoWoze 希望将验证与数据规范化相结合,以便为缺失的字段提供默认值。
解决方案
- 将数据验证与数据规范化分开
理由
- 理由;;验证和规范化可以被认为是独立的过程
- proc1;;区分不可接受的输入和可接受的输入
- (垃圾vs宝)
- (已验证与未验证)
- (良构与非良构)
- proc2;;优化可接受输入的内容
- proc1;;区分不可接受的输入和可接受的输入
例子
- 以下示例创建并应用两个模式
一个模式提供默认值,另一个进行验证
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'"]}