top-level marshmallow schema validation

djh picture djh · Nov 30, 2015 · Viewed 8.9k times · Source

From Marshmallow#validation, I know I can register validators on specific fields in a Schema. If a validator fails, errors in :

data, errors = MySchema().load({"some":"data})

will include error information for any field which has failed validators :

errors
# => some error message for the field that failed 

My question : Is it possible to validate at the Schema level (rather than at individual field level) and still return an error in the above way?

As an arbitrary example, say I wanted to validate that you tried to MySchema().load() n distinct keys. I currently have a @pre_load method which checks the structure of the input and raise ValidationError('message') if the data is ill-formed, but I would like to return it as result.errors like field validation does. What are my options?

Answer

Maxim Kulkin picture Maxim Kulkin · Dec 1, 2016

You can use validates_schema decorator to run validations on whole object:

class MySchema(marshmallow.Schema):
    # ...

    @marshmallow.validates_schema(skip_on_field_errors=True)
    def validate_object(self, data):
        if data['foo'] < data['bar']:
            raise marshmallow.ValidationError(
                'Value should not be less than bar',
                ['foo']  # name of field to report error for
            )

Although if you want to report multiple errors for different fields independently, Marshmallow at this moment does not support reporting multiple different errors for different fields, and you need to put separate validations into separate methods:

class MySchema(Schema):
    # ...

    @validates_schema
    def validate_foo(self, data):
        pass

    @validates_schema(skip_on_field_errors=True)
    def validate_bar(self, data):
        pass