如何为其值是包含不同类型的单个值的列表的字典构建棉花糖模式?

How to construct a marshmallow Schema for a dictionary whose values are lists holding a single value of different types?

我有一个 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"]}
}

还有更多 key:value 对,但这足以说明单值列表中的对象是不同类型的。我正在构建一个 Marshmallow Schema,我有以下内容:

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.Dict() ('Properties') 的值参数中的 fields.List() 对象要求我传递 'cls_or_instance',但我卡住了,因为我无法将字段类型列表或单一类型传递给它,因为类型各不相同。

有人愿意插嘴吗? :)

有几个选项可以通过使用 Marshmallows Custom Fields(非常强大)来实现您正在寻找的行为。

在您的案例中,我能想到的实现通用字段的最简单方法是使用 MethodField。请注意,这不会为您提供任何类型的验证,但也会接受列表以外的其他输入。 Serialization/Deserialization 因此可能会引发错误。

但是可以很容易地扩展 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))