Как использовать Schema.from_dict () для вложенных словарей? - PullRequest
1 голос
/ 01 октября 2019

Я пытаюсь создать класс Schema, используя вложенные словари, у которых есть некоторый список в качестве элементов. Однако, когда я делаю dumps (), сбрасываются только элементы верхнего уровня.

Иметь api rest, который возвращает список определенных вещей, например. список пользователей. но схема такова, что определенные сводные данные отправляются на верхний уровень, данные выглядят примерно так. Это то, что я ожидаю в качестве результата:

   {
        "field1": 5,
        "field2": false,
        "field3": {
            "field4": 40,
            "field5": [
                        {
                            "field6": "goo goo gah gah",
                            "field7": 99.341879,
                            "field8": {
                                "field9": "goo goo gah gah",
                                "field10": "goo goo gah gah"
                        }
             }]
         }
    }  

Вот мой код:

MySchema = Schema.from_dict(
   {
        "field1": fields.Int(),
        "field2": fields.Bool(),
        "field3": {
            "field4": fields.Int(),
            "field5": [
                        {
                            "field6": fields.Str(),
                            "field7": fields.Float(),
                            "field8": {
                                "field9": fields.Str(),
                                "field10": fields.Str()
                        }
             }]
         }
    }            
)

#Then use it like:

response = MySchema().dumps(data)

Фактический результат:

"{\"field1\": 5, \"field2\": false}"

1 Ответ

4 голосов
/ 01 октября 2019

Опция 1

Вы ищете несколько вложенных схем, связанных через fields.Nested:

from marshmallow import Schema, fields


Field8Schema = Schema.from_dict({
    "field9": fields.Str(), 
    "field10": fields.Str()
})

Field5Schema = Schema.from_dict({
    "field6": fields.Str(),
    "field7": fields.Float(),
    "field8": fields.Nested(Field8Schema),
})

Field3Schema = Schema.from_dict({
    "field4": fields.Int(), 
    "field5": fields.List(fields.Nested(Field5Schema))
})

MySchema = Schema.from_dict({
    "field1": fields.Int(),
    "field2": fields.Bool(),
    "field3": fields.Nested(Field3Schema),
})

MySchema().dump(data)

# {'field2': False,
#  'field1': 5,
#  'field3': {'field4': 40,
#   'field5': [{'field6': 'goo goo gah gah',
#     'field8': {'field9': 'goo goo gah gah', 'field10': 'goo goo gah gah'},
#     'field7': 99.341879}]}}

Опция 2

ЕслиВложение не будет таким глубоким, возможно, будет проще использовать decorators, то есть данные о гнезде и гнезде, как в документах :

class UserSchema(Schema):
    @pre_load(pass_many=True)
    def remove_envelope(self, data, many, **kwargs):
        namespace = 'results' if many else 'result'
        return data[namespace]

    @post_dump(pass_many=True)
    def add_envelope(self, data, many, **kwargs):
        namespace = 'results' if many else 'result'
        return {namespace: data}

Он чувствует, что он хорошо подходит для вашего случая.

Комментарии

Я бы предложил не использовать from_dict, поскольку он менее читаем для таких сложных данных, и вместо этого переключиться на класс-на основе схемы.

Существует множество хороших примеров вложений в документах.

...