如何从使用Cerberus验证失败的文档中删除字段?

时间:2017-10-23 14:58:25

标签: python cerberus

我使用开源Python数据验证库Cerberus来验证字典的结构。我希望它获取一个部分无效的文档并输出它而没有无效的密钥。

例如,对于此脚本:

from cerberus import Validator

schema = {'name': {'type': 'string'}, 
          'user_id': {'type': 'integer'}}
document = {'name': 'john doe', 'user_id': 'fdfdfd'}
v = Validator(schema)
v.validated(document)

这会返回None,因为验证失败。

有没有办法让文档只包含经过验证的字段,如下所示:

{'name': 'john doe'}

3 个答案:

答案 0 :(得分:3)

这是比@ jdoe更安全的解决方案,因为Validator.errors属性的结构不一定与文档的结构相关。但是document_error_tree提供了这样的内容。

def remove_invalid_fields(document, errors_tree):
    if errors_tree is None:
        return document
    filtered = {}
    for field, value in document.items():
        if field in errors_tree.descendants:
            continue
        if isinstance(value, Mapping):
            value = remove_invalid_fields(value, errors_tree[field])
        filtered[field] = value
    return filtered

schema = {'name': {'type': 'string'},
          'user_id': {'type': 'integer'}}
document = {'name': 'john doe', 'user_id': 'fdfdfd'}
validator = Validator(schema)

validator(document)
result = remove_invalid_fields(document, validator.document_error_tree)
assert result == {'name': 'john doe'}

它还会考虑子文档中的错误。

答案 1 :(得分:1)

代码:

validDoc = {}
for key in document:
    if key not in v.errors:
        validDoc[key] = document[key]
print(validDoc)

生成此输出:

{'name': 'john doe'}

答案 2 :(得分:0)

您是否考虑过purge_unknown选项?

>>> v = Validator({'foo': {'type': 'string'}}, purge_unknown=True)
>>> v.normalized({'bar': 'foo'})
{}

在上面的示例中,bar未知,因此它被清除。请注意,我们在此处使用normalized,请参阅the docs