Marshmallow: Ignore validation error and load a partial collection

Created on 15 Aug 2018  路  1Comment  路  Source: marshmallow-code/marshmallow

class Item(Schema):
    number = fields.Int(required=True)
    other_number = fields.Int(required=True)

collection = Item.load([{'number': '3', 'other_number': '4'}, {'number': '', 'other_number': '3'}], many=True)

Is there a way I can get:
collection == [{'number': 3, other_number: 4}]

That is make a best effort when serializing?

I've tried Nested fields, with validation error an getting valid_data, but if one field is valid, you get something like:

[{'number': 3, 'other_number': 4}, {'other_number': 3}]

Which is not what I want, that is I would like to load a collection ignore those that don't validate.

question

Most helpful comment

You could take advantage of the fact that ValidationError.messages is keyed by index when many=True to filter the valid data.

On marshmallow 3 it would look something like:

from marshmallow import Schema, fields, ValidationError


class Item(Schema):
    number = fields.Int(required=True)
    other_number = fields.Int(required=True)


try:
    Item().load(
        [{"number": "3", "other_number": "4"}, {"number": "", "other_number": "3"}],
        many=True,
    )
except ValidationError as error:
    filtered = [
        datum for i, datum in enumerate(error.valid_data) if i not in error.messages
    ]

print(filtered)
# [{'number': 3, 'other_number': 4}]

>All comments

You could take advantage of the fact that ValidationError.messages is keyed by index when many=True to filter the valid data.

On marshmallow 3 it would look something like:

from marshmallow import Schema, fields, ValidationError


class Item(Schema):
    number = fields.Int(required=True)
    other_number = fields.Int(required=True)


try:
    Item().load(
        [{"number": "3", "other_number": "4"}, {"number": "", "other_number": "3"}],
        many=True,
    )
except ValidationError as error:
    filtered = [
        datum for i, datum in enumerate(error.valid_data) if i not in error.messages
    ]

print(filtered)
# [{'number': 3, 'other_number': 4}]
Was this page helpful?
0 / 5 - 0 ratings