Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help to deserialize complex JSON #873

Closed
vcamaral opened this issue Jul 5, 2018 · 14 comments
Closed

Help to deserialize complex JSON #873

vcamaral opened this issue Jul 5, 2018 · 14 comments
Labels

Comments

@vcamaral
Copy link

vcamaral commented Jul 5, 2018

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)
@deckar01
Copy link
Member

deckar01 commented Jul 5, 2018

What version of marshmallow are you using? Can you edit your example so that the data and the schema match?

@vcamaral
Copy link
Author

vcamaral commented Jul 5, 2018

marshmallow==2.15.3

The example is correct!
I'm trying to deserialize JSON into object (which has a structure different from the original).

@vcamaral
Copy link
Author

vcamaral commented Jul 5, 2018

I tried this way but didn't work:

phones = fields.Nested(Phone, load_from='phones.list', many=True)

@deckar01
Copy link
Member

deckar01 commented Jul 5, 2018

Loading from a nested field name is not currently supported. #611 is a feature request for that syntax.

@vcamaral
Copy link
Author

vcamaral commented Jul 5, 2018

But there is another way to do this without using Nested field?

@deckar01
Copy link
Member

deckar01 commented Jul 5, 2018

Create a schema for the intermediate container, then "pluck" the list value out of it into the parent schema.

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

class Phones(Schema):
    list = fields.Nested(Phone, many=True)

class Contact(Schema):
    key = fields.Str()
    phones = fields.Nested(Phones, only='list')

#823 should make this a little more intuitive in v3 with a dedicated Pluck field.

@vcamaral
Copy link
Author

vcamaral commented Jul 5, 2018

I try this way:

class Item(OrderedSchema):
    id = fields.Int()

class Phone(OrderedSchema):
    items = fields.Nested(Item, many=True)

class Contact(OrderedSchema):
    key = fields.Str()
    phones = fields.Nested(Phone, only='items')

But not works:

[
    {
        "key": "1042F608-84C0-4F11-A685-61D06394EF0D",
        "phones": {
            "items": [
                {
                    "id": 1
                }
            ]
        }
    }
]

The expected result is:

[
    {
        "key": "1042F608-84C0-4F11-A685-61D06394EF0D",
        "phones": [
            {
                "id": 1
            }
        ]
    }
]

@vcamaral
Copy link
Author

vcamaral commented Jul 5, 2018

Can u help me @deckar01?

I try update to 3.0.0b12 (latest beta version) to use Pluck, but raise this error:
AttributeError: module 'marshmallow.fields' has no attribute 'Pluck'

With Pluck i try do this:

phones = fields.Pluck(Phone, 'items', many=True)

@lafrech
Copy link
Member

lafrech commented Jul 5, 2018

Pluck is work in progress. It is not available yet.

@vcamaral
Copy link
Author

vcamaral commented Jul 5, 2018

@lafrech but there is another way to do this without using Pluck?

@lafrech
Copy link
Member

lafrech commented Jul 5, 2018

See #873 (comment).

@vcamaral
Copy link
Author

vcamaral commented Jul 5, 2018

@lafrech this didn't work.
See result and expected result here.
I need hide items in the expected result.

@SVilgelm
Copy link

SVilgelm commented Aug 21, 2018

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


class Email(marshmallow.Schema):
    id = marshmallow.fields.Int()
    email = marshmallow.fields.Email()


class Emails(marshmallow.Schema):
    emails = marshmallow.fields.Nested(Email, many=True)

    @marshmallow.pre_load
    def load_emails(self, data):
        data['emails'] = data['emails']['items']
        return data


print(Emails().load(data))
# {'emails': [{'id': 1, 'email': '[email protected]'}, {'id': 2, 'email': '[email protected]'}]}

@lafrech
Copy link
Member

lafrech commented Sep 18, 2018

Please reopen if still stuck.

BTW, Pluck field was just released (in Marshmallow 3 beta).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants