Проверка зависимостей с использованием Цербера - PullRequest
1 голос
/ 21 июня 2019

Я проверяю файл CSV с Цербер , но борюсь с тем, что, как я предполагаю, является некоторой базовой логикой

Сценарий:

Файл CSV имеет 2 столбца. Column 2 требует иметь значение, только если Column 1 имеет значение. Если 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 означает отсутствие ошибки

Я проверил поднятые проблемы на github , но не могу найти никакого очевидного решения.

Ответы [ 2 ]

1 голос
/ 21 июня 2019

Примечание
При оценке этого правила (dependencies) не учитываются любые ограничения, определенные с помощью правила required.

Какими бы ни были "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 / ru / stable / validation-rules.html # зависимости


Обновление :

Решение для вашего условия " Сделайте col2 обязательным, если в col1 есть значение.».
Чтобы применить сложные правила - создайте пользовательский 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 следует обрабатыватькак пустое (для настройки пользовательских правил валидатора).


Расширенная версия для указания имени поля "зависимость":

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"},
}

http://docs.python -cerberus.org/en/stable/customize.html

0 голосов
/ 24 июня 2019

Предполагая, что вы преобразовали свой ввод CSV в список документов, вы можете сначала предварительно обработать документы, чтобы удалить поле col2 там, где оно пустое:

for document in documents:
    if not document["col2"]:
        document.pop("col2")

Тогда эта схема будет делатьзадание:

{"col1": {
    "oneof": [
        {"empty": True},
        {"empty": False, "dependencies": "col2"}
    ]
}}

Помните, что правила dependencies и required не учитывают значение поля, а только наличие поля в документе.

...