Как я могу вернуть пользовательское имя правила / код ошибки, используя Цербер? - PullRequest
1 голос
/ 08 июля 2019

Я проверяю файл .csv, и я хочу предоставить результаты проверки в формате, к которому привык пользователь. Чтобы использовать Цербер , я позволил пользователю определить правила проверки в файле .yaml.

schema.yaml

Rules:
 Rule1:
  maxlength: 10

 Rule2:
  allowed: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]

 Rule3:
  required: True

Затем я сопоставил эти правила со столбцами в файле CSV, к которым они применяются.

csv_fields.yaml

Fields:
 1:
  rules:
   - Rule1
   - Rule2

 2:
  rules:
   - Rule2
   - Rule3

 3:
  rules:
   - Rule1
   - Rule3

sample_file.csv

Ниже приведен пример файла с тремя столбцами: first_name, day_of_week и is_employed.

Peter, XX, True

Чтобы проверить, используя Cerberus, я делаю перекрестную ссылку rules, определенную в ключе rules документа csv_fields.yaml, с Rules в файле schema.yaml. Это легко сделать, поскольку .yaml файлы читаются как словари в python в формате ключ-значение.

Моя проблема

В приведенных выше примерах данных Цербер с ошибкой выдает 'day_of_week': ['unallowed value XX'], но пользователь не знает, какое правило вызвало эту ошибку.

Я с нетерпением жду, чтобы сообщить пользователю, что ошибка unallowed value XX была вызвана Rule2, поскольку пользователь знает Rule2, а не техническое конкретное определение Цербера.

Есть ли способ достичь этого, даже если это означает определение schema.yaml по-другому?

Я просматривал раздел ошибок Цербера , но, похоже, не могу найти способ сделать это.

Обновление:

Итак, я попытался добавить поле meta в определение правила в schema.yaml

Rules:
 Rule1:
  maxlength: 10
  meta: {'rule_name': "Rule1"}

Но при тестировании я не могу получить доступ к этому мета-ключу из-за возникшей ошибки, так как не могу найти его в document_error_tree или даже schema_error_tree.

1 Ответ

1 голос
/ 09 июля 2019

Я был в том же месте, что и вы, я расскажу вам, что я сделал.

Создал пользовательский обработчик ошибок и добавьте в сообщения об ошибках понятные человеку ключи.

from cerberus.errors import BasicErrorHandler

class CustomErrorHandler(BasicErrorHandler):
        def __init__(self, schema):
            self.custom_defined_schema = schema

        def _format_message(self, field, error):
            return self.custom_defined_schema[field].get('meta', {}).get('rule_name', field) + ': ' + super(CustomErrorHandler, self)._format_message(field, error)

val = Validator(schema, error_handler=CustomErrorHandler(schema))

Это то, что я сделал, надеюсь, это может пригодиться вам.

...