Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deserialize complex JSON using Marshmallow

I need to deserialize this JSON:

{
    "emails": {
        "items": [
            {
                "id": 1,
                "email": "[email protected]"
            },
            {
                "id": 2,
                "email": "[email protected]"
            }
        ]
    }
}

Into this object using Marshmallow:

{
    "emails": [
        {
            "id": 1,
            "email": "[email protected]"
        },
        {
            "id": 2,
            "email": "[email protected]"
        }
    ]
}

How can I do it?

I tried this way, which I found more intuitive, but it did not work:

class Phone(OrderedSchema):
    id = fields.Int()
    email = fields.Str()

class Contact(Schema):
    key = fields.Str()
    phones = fields.Nested(Phone, load_from='phones.list', many=True)
like image 784
Vinícius Amaral Avatar asked May 08 '26 08:05

Vinícius Amaral


1 Answers

Use the following code, I used Dict and Nested:

from marshmallow import Schema, fields, post_load


class Contact(Schema):
    """Schema for emails."""

    # Define subschema for serializing each item
    class Item(Schema):
        """Subclass for each item."""

        id = fields.Integer(required=True)
        email = fields.Email(required=True)
        

    # Define the fields in the main schema, here we define "emails" as a dict that accepts
    # strings for keys and list of Item(Schema) as values
    emails = fields.Dict(keys=fields.String(), values=fields.Nested(Item, many=True))

    # Define the way you want the schema to return the data
    @post_load
    def deserialize(self, data, **kwargs):
        """Deserialize in an specific way."""
        # post_load needs to return the data that the schema will return after deserialization
        
        return {
            "emails": [item for item in data["emails"]["items"]]
        }

Contact().load({
    "emails": {
        "items": [
            {
                "id": 1,
                "email": "[email protected]"
            },
            {
                "id": 2,
                "email": "[email protected]"
            }
        ]
    }
})
# Returns
#{'emails': [{'email': '[email protected]', 'id': 1},
# {'email': '[email protected]', 'id': 2}]}
like image 124
Loscil94 Avatar answered May 10 '26 22:05

Loscil94



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!