Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing `None` on load and skipping `None` on dump

I'm using marshmallow 2.0.0rc2 to validate input data on HTTP requests and to load SQLAlchemy models to JSON on HTTP responses. And i've stumbled upon 2 problems:

First, while loading data from JSON on HTTP PUT request, i want to populate all missing fields as None, to correctly overwrite data in SQLAlchemy. Right now i'm using following code:

for name, field in schema.fields.iteritems():
    if field.missing == ma.missing:
        schema.fields[name].missing = None

It works, but i suppose it's bugged since i'm messing with marshmallow.Field instance attached to Schema class. And after disposing Schema instance all fields we patched will stuck with new missing instead of default one.

Second, while dumping data from SQLAlchemy to JSON all missing fields are resolved as None, and JSON populated with {"key": null, } data. It's unwanted behaviour and i'm cleaning them on post_dump trigger.

@post_dump
def clean_missing(self, data):
    for key in filter(lambda key: data[key] is None, data):
        data.pop(key)
    return data

Same as previous, it's working but includes creating some BaseSchema class witch passes this logic to all inherited classes.

I've searched documentation for while, and didn't find any correct way to swap this behaviours i.e. skip fields on dumping and populate fields with None on loading. Am I missing something or marshmallow don't provide such functions?

like image 878
Gening D. Avatar asked Sep 23 '15 13:09

Gening D.


1 Answers

To force None on load, you can use the missing parameter:

missing – Default deserialization value for the field if the field is not found in the input data. May be a value or a callable.

class ExampleSchema(Schema):
    field_a = fields.Int(missing=None)

Regarding your second point, the docs seem to say that from 2.0 on, missing fields are excluded from serialized output.

like image 144
Jérôme Avatar answered Sep 22 '22 14:09

Jérôme