Как построить схему зефира для словаря, значения которого представляют собой списки, содержащие одно значение разных типов? - PullRequest
0 голосов
/ 07 августа 2020

У меня есть объект json, который выглядит так:

 dic = {
     "_id": "3cef538d-0199-477e-bbf7-2a0d26d92724",
     "sID": "44155700-8476-4473-a636-685d6df021c5",
     "tID": "c48ac367-8583-43d6-959e-90d25ba1887c",
     "Type": "ParamData",
     "Param": {

         "SRT": [1589196207.91999],
         "BFW": [False],
         "INS": ["Matrix-M"],
         "LWN": [15798],
         "AN2": [0],
         "CRR": [0],
         "DUR": [4.97799682617188],
         "SRN": ["336"],
         "PKA": [-20704],
         "SSP": [True],
         "ABP": [32993],
         "AN1": [0.221665252948623],
         "PRL": [7278],
         "VSN": ["2.240 Nov 16 2011"]}
}

Есть больше пар ключ: значение, но этого достаточно, чтобы понять, что внутри однозначных списков объекты имеют различные виды. Я создаю схему Marshmallow, и у меня есть следующее:

class PQMetaSchema(Schema):
    _id = fields.Str()
    spec_igID = fields.Str(data_key='Spec_IG')
    
    paramID = fields.Str()
    fields.B
    
    Type = fields.Str(attribute='MetaData')
    Properties = fields.Dict(keys=fields.Str(), values=fields.List())

Однако объект fields.List () в аргументе значений fields.Dict () ('Properties') требует, чтобы я передал a 'cls_or_instance', но я застрял, так как не могу передать ему ни список типов полей, ни один тип, поскольку типы различаются.

Кто-нибудь хочет вмешаться? :)

1 Ответ

0 голосов
/ 07 августа 2020

Существует несколько вариантов реализации искомого поведения с помощью настраиваемых полей Marshmallows (которые довольно эффективны).

Самая простая реализация, которую я мог придумать для реализации generi Поле c в вашем случае использует MethodField. Обратите внимание, что это не даст вам никакой проверки, но также принимает другие входные данные, кроме списков. Поэтому сериализация / десериализация может вызвать ошибки.

Но функции get и load можно легко расширить, или вы можете добавить функцию проверки.

from marshmallow import fields, Schema


class PQMetaSchema(Schema):

    Properties = fields.Method("get_properties", deserialize="load_properties", data_key="Param")

    def get_properties(self, obj):
        return obj["Properties"]

    def load_properties(self, value):
        return dict(value)

dic = {
    "Param": {
        "SRT": [1589196207.91999],
        "BFW": [False],
        "INS": ["Matrix-M"],
        "LWN": [15798],
        "AN2": [0],
        "CRR": [0],
        "DUR": [4.97799682617188],
        "SRN": ["336"],
        "PKA": [-20704],
        "SSP": [True],
        "ABP": [32993],
        "AN1": [0.221665252948623],
        "PRL": [7278],
        "VSN": ["2.240 Nov 16 2011"]}
}

meta_schema_dict = PQMetaSchema().load(dic)
print(meta_schema_dict)
print(PQMetaSchema().dump(meta_schema_dict))
...