python - 使用 Marshmallow 的嵌套模式自动字典键解析

标签 python serialization nested schema marshmallow

我有一个 Marshmallow 模式,其中对象使用键来引用在结构的另一部分的字典中定义的对象。我希望在反序列化对象时自动解析 key 。我怎样才能以惯用的方式在 Marshmallow 中实现这种效果?

目前的解决方法是手动解析所有引用,但这看起来很笨拙,因为 Marshmallow 的声明性质应该能够自动为我们完成。

请注意,Marshmallow-SQLAlchemy 在 columns are declared as relationships 时支持这种(反)序列化。 "它会自动为我们执行此操作,但我想使用 JSON 数据执行此操作。

这是我想要实现的示例,fields.Relationship 是尚不存在的东西:

class UserSchema(Schema):
    name = fields.String()
    email = fields.Email()
    friends = fields.Relationship('self', path="AddressBook.contacts", many=True)

class AddressBookSchema(Schema):
    contacts = nested.Dict(keys=fields.String(), values=fields.Nested(UserSchema))

# ... create ``user`` ...
serialized_data = AddressBookSchema().dump(user)
pprint(serialized_data)
# "contacts": {
#   "Steve": {
#     "name": "Steve",
#     "email": "steve@example.com",
#     "friends": ["Mike"]
#   },
#   "Mike": {
#     "name": "Mike",
#     "email": "mike@example.com",
#     "friends": []
# }


deserialized_data = UserSchema().load(result)
pprint(deserialized_data)
# "contacts": {
#   "Steve": {
#     "name": "Steve",
#     "email": "steve@example.com",
#     "friends": [ {"name": "Mike", "email": "mike@example.com"]
#   },
#   "Mike": {
#     "name": "Mike",
#     "email": "mike@example.com",
#     "friends": []
# }

我还提交了 issue on the Marshmallow Github repository .

最佳答案

为什么不简单地用 post_load 传输中间数据呢?钩子(Hook):

class UserSchema(Schema):
    name = fields.String()
    email = fields.Email()
    friends = fields.List(fields.String())

class AddressBookSchema(Schema):
    contacts = fields.Dict(keys=fields.String(), values=fields.Nested(UserSchema))

    @post_load
    def trans_friends(self, item):
        for name in item['contacts']:
            item['contacts'][name]['friends'] = [item['contacts'][n] for n in item['contacts'][name]['friends']]


data = """
{
 "contacts": {
  "Steve": {
    "name": "Steve",
    "email": "steve@example.com",
    "friends": ["Mike"]
  },
  "Mike": {
    "name": "Mike",
    "email": "mike@example.com",
    "friends": []
  }
 }
}
"""

deserialized_data = AddressBookSchema().loads(data)
pprint(deserialized_data)

产量:

UnmarshalResult(data={'contacts': {'Steve': {'name': 'Steve', 'email': 'steve@example.com', 'friends': [{'name': 'Mike', 'email': 'mike@example.com', 'friends': []}]}, 'Mike': {'name': 'Mike', 'email': 'mike@example.com', 'friends': []}}}, errors={})

关于python - 使用 Marshmallow 的嵌套模式自动字典键解析,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51992551/

相关文章:

python 脚本 envoke -h 或 --help 如果没有选择任何选项

json - 将 TypeNameAssemblyFormat 与 PCL 一起使用时,Newtonsoft.Json 出现 MissingMethodException

java - 如何在 Java 中存储不可序列化对象的引用? (安卓)

asp.net-mvc - DefaultModelBinder 嵌套级别+其他绑定(bind)器的问题

python - 从具有重复键的字典列表中创建具有唯一键的字典列表

python - 如何为 Python 安装 yaml 包?

c# - 如何在 C# 中通过网络发送任意对象

c++ - 嵌套模板类型的部分特化在 VC++ 2012 编译器中生成 "internal error"

javascript - 如何将一个字符串分解成多个重叠的更小的字符串?

python - QtWebEngine 拦截带有自定义 URL 模式服务回复的请求