【问题标题】:Automatic dictionary key resolution with nested schemas using Marshmallow使用 Marshmallow 使用嵌套模式自动解析字典键
【发布时间】:2019-01-30 05:33:38
【问题描述】:

我有一个 Marshmallow 模式,其中对象使用键来引用在结构的另一部分的字典中定义的对象。我希望在反序列化对象时自动解析密钥。如何以惯用的方式在 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

【问题讨论】:

    标签: python serialization nested schema marshmallow


    【解决方案1】:

    为什么不用post_load 钩子简单地传输中间数据:

    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={})
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-01-18
      • 2021-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 2019-11-29
      相关资源
      最近更新 更多