使用棉花糖使用嵌套模式自动词典密钥解析 [英] Automatic dictionary key resolution with nested schemas using Marshmallow

查看:110
本文介绍了使用棉花糖使用嵌套模式自动词典密钥解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个棉花糖模式,其中对象使用键来引用结构另一部分中字典中定义的对象.我想在反序列化对象时让键自动解析.如何以惯用的方式在棉花糖中实现这种效果?

I have a Marshmallow schema where an objects use a key to refer to an object that is defined in a dictionary in another part of the structure. I want to have the key automatically resolved when deserializing the object. How can I achieve this effect in Marshmallow in an idiomatic manner?

目前的解决方法是手动解析所有引用,但这似乎很笨拙,因为棉花糖的声明性性质应该能够为我们自动完成.

The workaround for now is to resolve all of the references manually, but this seems clunky, since the declarative nature of Marshmallow should be able to do it for us automatically.

请注意,当

Note that Marshmallow-SQLAlchemy supports this kind of (de-)serialization when columns are declared as relationships" which do this automatically for us, but I want to do it with JSON data.

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

Here is an example of what I want to achieve, with fields.Relationship being something that does not exist yet:

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": []
# }

我还已经在棉花糖Github存储库中提交了问题. /p>

I have also filed an issue on the Marshmallow Github repository.

推荐答案

为什么不简单地使用

why not simply transfer the intermediate data with a 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={})

这篇关于使用棉花糖使用嵌套模式自动词典密钥解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆