【问题标题】:Colander: How do I handle null values for nested schema滤锅:如何处理嵌套模式的空值
【发布时间】:2020-12-29 03:54:50
【问题描述】:

使用滤锅 1.5.1,如果我将 null 传递给由嵌套模式定义的属性:

class ChildSchema(colander.Schema):
    a = colander.SchemaNode(colander.Integer(), missing=None)
    b = colander.SchemaNode(colander.Integer(), missing=None)

class ParentSchema(colander.Schema):
    c = colander.SchemaNode(colander.Integer(), missing=None)
    d = ChildSchema(missing=None)
example json:
{
    "c": 1,
    "d": null
}

然后反序列化时出现此错误:

"\"None\" is not a mapping type: Does not implement dict-like functionality."

未按预期传递属性d 函数,并反序列化为None。如何正确处理反序列化传递给嵌套模式的 null 值?根据文档,我希望该行为返回NoneDeserialization Combinations

【问题讨论】:

    标签: python-3.5 colander


    【解决方案1】:

    请考虑以下几点:

    您需要以下导入。

    import colander
    from colander import SchemaType, Invalid, null
    

    以下与您的子架构相同。

    class ChildSchema(colander.Schema):
        a = colander.Schema(colander.Integer(), missing=None)
        b = colander.Schema(colander.Integer(), missing=None)
    

    下面是所有魔法发生的地方。我们创建自己的类型。请注意,它可能缺少滤锅 SchemaTypes 中的内置函数可能提供的一些基本功能(如序列化)。如果接收到的对象为 null 或 None ,则返回它而不进行任何更改。如果它不是 null 或 None 并且不是字典,它将引发错误,如果它是字典,它将使用 ParentSchema 序列化,即使 Parent 的属性为 null 或 None ({"d": null} )。

    class MyType(SchemaType):
        def deserialize(self, node, cstruct):
            if cstruct is null:
                return null
            if cstruct is None:
                return None
            if not isinstance(cstruct, dict):
                raise Invalid(node, '%r is not an object' % cstruct)
            else:
                return ChildSchema().deserialize(cstruct)
    

    我们使用魔法类型创建父模式:

    class ParentSchema(colander.Schema):
        c = colander.SchemaNode(colander.Integer(), missing=None)
        d = colander.SchemaNode(MyType(), missing=None)
    

    "d" 将按照您的意愿进行反序列化。现在让我们看看它的一些用法示例:

    schema = ParentSchema()
    

    示例 1.“d”为空(主要问题)

    schema.deserialize({"c": 1, "d": null})
    

    输出 1

    {"c": 1, "d": None}
    

    示例 2.“d”为无

    schema.deserialize({"c": 1, "d": None})
    

    输出 2

    {"c": 1, "d": None}
    

    示例 3. 正常行为

    schema.deserialize({'c': 1, 'd': {'a': 1}})
    

    输出 3。

    {'c': 1, 'd': {'a': 1, 'b': None}}
    

    示例 5. 错误 "d" is not dict

     schema.deserialize({'c': 1, 'd': [] })
    

    输出 5

     # Invalid: {'d': '[] is not an object'}
    

    示例 6. 错误验证器不是数字

     schema.deserialize({'c': 1, 'd': {'a': "foobar"}})
    

    输出 6

    # Invalid: {'a': u'"foobar" is not a number'}
    

    为了写这个答案,我使用了https://docs.pylonsproject.org/projects/colander/en/latest/extending.html 作为来源。

    【讨论】:

      猜你喜欢
      • 2018-12-27
      • 2019-04-13
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 2014-12-11
      • 2020-07-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多