Marshmallow: attribute used instead of data_key during deserialization

Created on 2 May 2018  路  6Comments  路  Source: marshmallow-code/marshmallow

This may be related to #748. When a data_key is provided for a field the deserialized data contains the wrong key.

```python
import marshmallow as mm

class TestSchema(mm.Schema):
type = mm.fields.String(attribute='_type', data_key='type')

data = {
'type': 'value'
}

assert TestSchema().load(data) == data

Most helpful comment

Use one schema for loading and one for dumping.

class FooLoad(Schema):
    name = fields.Str()
    email = fields.Email(data_key='emailAddress')

class FooDump(Schema):
    name = fields.Str()
    email = fields.Email()

schema_dump = FooDump()
schema_dump.dump({'name': 'foo', 'email': '[email protected]'})
# {'name': 'foo', 'email': '[email protected]'}

schema_load = FooLoad()
schema_load.load({'name': 'foo', 'emailAddress': '[email protected]'})
# {'name': 'foo', 'email': '[email protected]'}

All 6 comments

data_key is the key used to get the value in the input data. Setting it to the same string as the field name should be a no op.

attribute is the key used for the deserialized data, so you get {'_type': 'value'}. This is the right behaviour.

What are you trying to achieve?

I don't see a use case for using both data_key and attribute. (Unless you want to build Schemas programatically, maybe.)

_type is a discriminator column on my model. I want to serialize _type as type, and leave it as type on deserialization.

I suppose I can use it as _type after deserialization. The value specifies which model class needs to be instantiated and will likely be removed before the data is passed to the newly created model object.

I want to serialize _type as type, and leave it as type on deserialization.

You could do that with marshmallow 2 but it is not possible anymore with MA3. To do that, you'd need two different Schemas for serialization/deserialization.

I suppose I can use it as _type after deserialization. The value specifies which model class needs to be instantiated and will likely be removed before the data is passed to the newly created model object.

Yes, probably. Or leave it as type and remove both attribute and data_key.

I'll just delete the _type key so I don't have to update all my models. Thanks for your help! This issue can be closed.

@lafrech sorry for bringing this old thread to life again, but

You could do that with marshmallow 2 but it is not possible anymore with MA3. To do that, you'd need two different Schemas for serialization/deserialization.

How would one use two different schemas? I run into the same situation as the author:

class Foo(Schema):
    name = fields.Str()
    email = fields.Email(data_key='emailAddress')

schema = Foo()
data = {
    'name': 'foo',
    'emailAddress': '[email protected]'

I wanted dump to show 'email' rather than 'emailAddress'. I am using 3.0.

Use one schema for loading and one for dumping.

class FooLoad(Schema):
    name = fields.Str()
    email = fields.Email(data_key='emailAddress')

class FooDump(Schema):
    name = fields.Str()
    email = fields.Email()

schema_dump = FooDump()
schema_dump.dump({'name': 'foo', 'email': '[email protected]'})
# {'name': 'foo', 'email': '[email protected]'}

schema_load = FooLoad()
schema_load.load({'name': 'foo', 'emailAddress': '[email protected]'})
# {'name': 'foo', 'email': '[email protected]'}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

tadams42 picture tadams42  路  3Comments

imhoffd picture imhoffd  路  3Comments

agatheblues picture agatheblues  路  3Comments

pd-Shah picture pd-Shah  路  4Comments

jayennis22 picture jayennis22  路  4Comments