使用 Cerberus 进行依赖关系验证
Dependencies validation using Cerberus
我正在使用 Cerberus 验证 CSV 文件,但正在为我假设的一些基本逻辑而苦苦挣扎
场景:
一个 CSV 文件有 2 列。仅当 Column 1
有值时,Column 2
才需要有值。如果 Column 1
为空,则 Column 2
也应为空。
我认为这将是编写的最直接的规则之一,但到目前为止,一切都没有按预期工作。
下面是使用 python 个字典的相同逻辑。
from cerberus import Validator
v = Validator()
schema = {
"col1": {"required": False},
"col2": {"required": True, "dependencies": "col1"},
}
document = {
"col1": "a",
"col2": ""
}
v.validate(document, schema) # This responds with True!? Why?
v.errors
{}
我本以为 Column 2
会出现错误,因为已经提供了 Column 1
,但这里的结果是 True
,意思是没有错误
我检查了 raised issues on github 但似乎找不到任何明显的解决方案。
Note
The evaluation of this rule (dependencies
) does not consider any constraints defined with the required
rule.
无论 "required"
是什么:
from cerberus import Validator
v = Validator()
document = {
"col1": "a",
"col2": ""
}
schema = {
"col1": {"required": False},
"col2": {"required": True, "dependencies": "col1"},
}
print(v.validate(document, schema)) # True
print(v.errors) # {}
schema = {
"col1": {"required": True},
"col2": {"required": True, "dependencies": "col1"},
}
print(v.validate(document, schema)) # True
print(v.errors) # {}
schema = {
"col1": {"required": True},
"col2": {"required": False, "dependencies": "col1"},
}
print(v.validate(document, schema)) # True
print(v.errors) # {}
http://docs.python-cerberus.org/en/stable/validation-rules.html#dependencies
更新:
针对您的情况“如果 col1 中有值,则强制要求 col2 的解决方案。”。
要应用复杂的规则 - 创建自定义 Validator,如下所示:
from cerberus import Validator
class MyValidator(Validator):
def _validate_depends_on_col1(self, depends_on_col1, field, value):
""" Test if a field value is set depending on `col1` field value.
"""
if depends_on_col1 and self.document.get('col1', None) and not value:
self._error(field, f"`{field}` cannot be empty given that `col1` has a value")
v = MyValidator()
schema = {
"col1": {"required": False},
"col2": {"required": True, "depends_on_col1": True},
}
print(v.validate({"col1": "a", "col2": ""}, schema)) # False
print(v.errors) # {'col2': ['`col2` cannot be empty given that `col1` has a value']}
print(v.validate({"col1": "", "col2": ""}, schema)) # True
print(v.errors) # {}
print(v.validate({"col1": 0, "col2": "aaa"}, schema)) # True
print(v.errors) # {}
请注意,您需要 运行 约定哪些列 col1
值应被视为空值(以调整自定义验证器规则)。
指定"dependancy"字段名称的扩展版本:
class MyValidator(Validator):
def _validate_depends_on_col(self, col_name, field, value):
""" Test if a field value is set depending on `col_name` field value.
"""
if col_name and self.document.get(col_name, None) and not value:
self._error(field, f"`{field}` cannot be empty given that `{col_name}` has a value")
v = MyValidator()
document = {"col1": "a", "col2": ""}
schema = {
"col1": {"required": False},
"col2": {"required": True, "depends_on_col": "col1"},
}
假设您将 csv 输入转换为文档列表,您可以先对文档进行预处理以删除空的 col2
字段:
for document in documents:
if not document["col2"]:
document.pop("col2")
那么这个模式就可以完成工作:
{"col1": {
"oneof": [
{"empty": True},
{"empty": False, "dependencies": "col2"}
]
}}
请注意,dependencies
和 required
规则不考虑字段的值,而只考虑文档中字段的存在。
我正在使用 Cerberus 验证 CSV 文件,但正在为我假设的一些基本逻辑而苦苦挣扎
场景:
一个 CSV 文件有 2 列。仅当 Column 1
有值时,Column 2
才需要有值。如果 Column 1
为空,则 Column 2
也应为空。
我认为这将是编写的最直接的规则之一,但到目前为止,一切都没有按预期工作。
下面是使用 python 个字典的相同逻辑。
from cerberus import Validator
v = Validator()
schema = {
"col1": {"required": False},
"col2": {"required": True, "dependencies": "col1"},
}
document = {
"col1": "a",
"col2": ""
}
v.validate(document, schema) # This responds with True!? Why?
v.errors
{}
我本以为 Column 2
会出现错误,因为已经提供了 Column 1
,但这里的结果是 True
,意思是没有错误
我检查了 raised issues on github 但似乎找不到任何明显的解决方案。
Note
The evaluation of this rule (dependencies
) does not consider any constraints defined with therequired
rule.
无论 "required"
是什么:
from cerberus import Validator
v = Validator()
document = {
"col1": "a",
"col2": ""
}
schema = {
"col1": {"required": False},
"col2": {"required": True, "dependencies": "col1"},
}
print(v.validate(document, schema)) # True
print(v.errors) # {}
schema = {
"col1": {"required": True},
"col2": {"required": True, "dependencies": "col1"},
}
print(v.validate(document, schema)) # True
print(v.errors) # {}
schema = {
"col1": {"required": True},
"col2": {"required": False, "dependencies": "col1"},
}
print(v.validate(document, schema)) # True
print(v.errors) # {}
http://docs.python-cerberus.org/en/stable/validation-rules.html#dependencies
更新:
针对您的情况“如果 col1 中有值,则强制要求 col2 的解决方案。”。
要应用复杂的规则 - 创建自定义 Validator,如下所示:
from cerberus import Validator
class MyValidator(Validator):
def _validate_depends_on_col1(self, depends_on_col1, field, value):
""" Test if a field value is set depending on `col1` field value.
"""
if depends_on_col1 and self.document.get('col1', None) and not value:
self._error(field, f"`{field}` cannot be empty given that `col1` has a value")
v = MyValidator()
schema = {
"col1": {"required": False},
"col2": {"required": True, "depends_on_col1": True},
}
print(v.validate({"col1": "a", "col2": ""}, schema)) # False
print(v.errors) # {'col2': ['`col2` cannot be empty given that `col1` has a value']}
print(v.validate({"col1": "", "col2": ""}, schema)) # True
print(v.errors) # {}
print(v.validate({"col1": 0, "col2": "aaa"}, schema)) # True
print(v.errors) # {}
请注意,您需要 运行 约定哪些列 col1
值应被视为空值(以调整自定义验证器规则)。
指定"dependancy"字段名称的扩展版本:
class MyValidator(Validator):
def _validate_depends_on_col(self, col_name, field, value):
""" Test if a field value is set depending on `col_name` field value.
"""
if col_name and self.document.get(col_name, None) and not value:
self._error(field, f"`{field}` cannot be empty given that `{col_name}` has a value")
v = MyValidator()
document = {"col1": "a", "col2": ""}
schema = {
"col1": {"required": False},
"col2": {"required": True, "depends_on_col": "col1"},
}
假设您将 csv 输入转换为文档列表,您可以先对文档进行预处理以删除空的 col2
字段:
for document in documents:
if not document["col2"]:
document.pop("col2")
那么这个模式就可以完成工作:
{"col1": {
"oneof": [
{"empty": True},
{"empty": False, "dependencies": "col2"}
]
}}
请注意,dependencies
和 required
规则不考虑字段的值,而只考虑文档中字段的存在。