如何使marshmallow在序列化时引发AttributeErrors

时间:2018-03-27 06:24:43

标签: python marshmallow

当数据缺少属性时,如何让marshmallow引发异常?

考虑以下示例:

In [8]: import marshmallow

In [9]: class Foo(marshmallow.Schema):
   ...:     bar = marshmallow.fields.Str(required=True)
   ...:

In [10]: class Bar:
    ...:     pass
    ...:

In [11]: bar = Bar()

In [12]: Foo().dumps(bar)
Out[12]: MarshalResult(data='{}', errors={})

In [13]: bar.bar
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-13-6901e83d9f0c> in <module>()
----> 1 bar.bar

AttributeError: 'Bar' object has no attribute 'bar'

更糟糕的是,这是:

In [14]: foo.loads(foo.dumps(bar).data)
Out[14]: UnmarshalResult(data={}, errors={'bar': ['Missing data for required field.']})

1 个答案:

答案 0 :(得分:1)

issue的以下引用解释了您在问题的第一部分中描述的行为。

  

这是设计的。主要出于性能原因,仅进行验证   在反序列化(loadvalidate)上发生。数据传递给   假设dump有效。

如果您需要验证,则期望您明确致电validate(),例如从你的例子:

In [10]: foo.validate(foo.dump(foo).data)
---------------------------------------------------------------------------
ValidationError                           Traceback (most recent call last)
<ipython-input-40-4dfb5988e928> in <module>()
----> 1 foo.validate(foo.dump(foo).data)

...

ValidationError: {'bar': ['Missing data for required field.']}

关于在反序列化期间缺乏验证,对于您正在使用的marshmallow版本,您必须明确声明架构是严格的&#39;以便验证自动发生。在您的示例中,这可以通过以下方式完成:

In [22]: class Foo(marshmallow.Schema):
    ...:     bar = marshmallow.fields.Str(required=True)
    ...:     class Meta:
    ...:         strict = True

In [23]: foo = Foo()

In [24]: foo.loads(foo.dumps(bar).data)
---------------------------------------------------------------------------
...
ValidationError: {'bar': ['Missing data for required field.']}

正如Issue 598中所述,此行为已更改,marshamallow的最新版本默认为此严格&#39;行为;它还会删除MarshalResult / UnmarshalResult包装器。