带有棉花糖的顶级列表和字典
Top level lists and dictionaries with marshmallow
是否可以为顶级列表(例如 obj = ['John', 'Bill', 'Jack']
)或字典(例如 obj = {'user1': 123, 'user2': 456, 'user3': 789}
- 键是任意的)定义棉花糖架构?
顶级字典是正常情况。要接受任意键,请参阅 unknown=INCLUDE,但是您没有验证,这与使用 Dict
字段时不同。
对此的解决方案是为未知字段定义一个默认字段,或者扩展字段以使其充当模式。前者已经被建议(我相信是我提出的)并且应该不难实现,但没有人花时间研究它。后者是由 Jared 建议的,将是一个重要的重构。没有人在研究它。
顶级字典列表是使用 many=True 模式的正常情况。任何东西的顶级列表都还无法实现。这将适用于上述重构。
作为 Jérôme ,参数 many=True
.
支持模式列表
对于键数未知的 dict
(但可能是已知的 key/value 类型),Dict
字段中的一切都已准备就绪。做一个小的subclass可以给人一种处理正常Schema
的感觉(至少w.r.t。dump
和load
),例如:
import typing
from marshmallow import fields
from marshmallow_dataclass import dataclass
class PoorMansDictSchema(fields.Dict):
@staticmethod
def _get_obj(obj, _attr, _default):
return obj
def dump(self, obj: typing.Any):
return self.serialize('', obj, accessor=self._get_obj)
def load(self, data: typing.Mapping[str, typing.Any]):
return self.deserialize(data)
@dataclass
class Record:
name: str
value: float
dict_schema = PoorMansDictSchema(keys=fields.Str(),
values=fields.Nested(Record.Schema))
records = {'a': Record('a', 1.0), 'b': Record('b', 2.0)}
print(records)
# {'a': Record(name='a', value=1.0), 'b': Record(name='b', value=2.0)}
serialized_records = dict_schema.dump(records)
print(serialized_records)
# {'a': {'name': 'a', 'value': 1.0}, 'b': {'name': 'b', 'value': 2.0}}
records_back = dict_schema.load(serialized_records)
print(records_back)
# {'a': Record(name='a', value=1.0), 'b': Record(name='b', value=2.0)}
我在示例中使用了 marshmallow-dataclass
以使其更简洁(从 class 推断出 Schema
)。显然,PoorMansDictSchema
的 dump
/load
不支持 many
、partial
和 unknown
覆盖 Schema
相关特权,但仍可在嵌套架构中定义这些特权。
是否可以为顶级列表(例如 obj = ['John', 'Bill', 'Jack']
)或字典(例如 obj = {'user1': 123, 'user2': 456, 'user3': 789}
- 键是任意的)定义棉花糖架构?
顶级字典是正常情况。要接受任意键,请参阅 unknown=INCLUDE,但是您没有验证,这与使用 Dict
字段时不同。
对此的解决方案是为未知字段定义一个默认字段,或者扩展字段以使其充当模式。前者已经被建议(我相信是我提出的)并且应该不难实现,但没有人花时间研究它。后者是由 Jared 建议的,将是一个重要的重构。没有人在研究它。
顶级字典列表是使用 many=True 模式的正常情况。任何东西的顶级列表都还无法实现。这将适用于上述重构。
作为 Jérôme many=True
.
对于键数未知的 dict
(但可能是已知的 key/value 类型),Dict
字段中的一切都已准备就绪。做一个小的subclass可以给人一种处理正常Schema
的感觉(至少w.r.t。dump
和load
),例如:
import typing
from marshmallow import fields
from marshmallow_dataclass import dataclass
class PoorMansDictSchema(fields.Dict):
@staticmethod
def _get_obj(obj, _attr, _default):
return obj
def dump(self, obj: typing.Any):
return self.serialize('', obj, accessor=self._get_obj)
def load(self, data: typing.Mapping[str, typing.Any]):
return self.deserialize(data)
@dataclass
class Record:
name: str
value: float
dict_schema = PoorMansDictSchema(keys=fields.Str(),
values=fields.Nested(Record.Schema))
records = {'a': Record('a', 1.0), 'b': Record('b', 2.0)}
print(records)
# {'a': Record(name='a', value=1.0), 'b': Record(name='b', value=2.0)}
serialized_records = dict_schema.dump(records)
print(serialized_records)
# {'a': {'name': 'a', 'value': 1.0}, 'b': {'name': 'b', 'value': 2.0}}
records_back = dict_schema.load(serialized_records)
print(records_back)
# {'a': Record(name='a', value=1.0), 'b': Record(name='b', value=2.0)}
我在示例中使用了 marshmallow-dataclass
以使其更简洁(从 class 推断出 Schema
)。显然,PoorMansDictSchema
的 dump
/load
不支持 many
、partial
和 unknown
覆盖 Schema
相关特权,但仍可在嵌套架构中定义这些特权。