如何为其值是包含不同类型的单个值的列表的字典构建棉花糖模式?
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))
我有一个 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))