问题
Am validating .csv
file and I want to give the results of the validation in a format the user is accustomed to. To make use of Cerberus, I've let the user to define the validation rules in a .yaml
file.
schema.yaml
Rules:
Rule1:
maxlength: 10
Rule2:
allowed: ["MO", "TU", "WE", "TH", "FR", "SA", "SU"]
Rule3:
required: True
I have then mapped those rules to the columns in the CSV file where they apply.
csv_fields.yaml
Fields:
1:
rules:
- Rule1
- Rule2
2:
rules:
- Rule2
- Rule3
3:
rules:
- Rule1
- Rule3
sample_file.csv
Below is a sample file that has three columns: first_name
, day_of_week
and is_employed
.
Peter, XX, True
To validate using Cerberus, am cross referencing the rules
defined in the rules
key of the csv_fields.yaml
document with the Rules
in the schema.yaml
file. This is easy to do as .yaml
files are read as dictionaries in python in a key-value format.
My Problem
In the above sample data, cerberus with throw the error 'day_of_week': ['unallowed value XX']
but a user won't know what rule triggered this error.
What am looking forward to tell the user is that the error unallowed value XX
was triggered by Rule2
as the user knows Rule2
rather than the technical Cerberus specific definition.
Is there a way to achieve this even if it means defining the schema.yaml
differently?
I've looked at the Cerberus Errors Section but can't seem to find a way to do this.
Update:
So I've tried adding a meta
field to the rule definition in schema.yaml
Rules:
Rule1:
maxlength: 10
meta: {'rule_name': "Rule1"}
But when I test, I can't seem to access this Meta Key from the Error raised as I can't find it in document_error_tree
or even schema_error_tree
.
回答1:
I was at the same space as you are, I'll tell you what I did.
Created a custom error_handler and prepend the error messages with human readable keys.
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))
This is what I did, hopefully it can be of use to you.
来源:https://stackoverflow.com/questions/56936542/how-do-i-return-a-custom-rule-name-error-code-using-cerberus