如何使棉花糖在序列化时引发 AttributeErrors
How to make marshmallow raise AttributeErrors on serialization
当数据缺少属性时,如何让 marshmallow make 引发异常?
考虑以下示例:
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.']})
此 issue 中的以下引述解释了您在问题的第一部分中描述的行为。
This is by design. Primarily for performance reasons, validation only
happens on deserialization (load
and validate
). The data passed to
dump
is assumed to be valid.
如果您需要验证,例如,您将显式调用 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
版本,您必须明确声明架构为 'strict' 以便自动进行验证。在您的示例中,这可以通过以下方式完成:
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
的最新版本默认为此 'strict' 行为;它还删除了 MarshalResult
/UnmarshalResult
包装器。
当数据缺少属性时,如何让 marshmallow make 引发异常?
考虑以下示例:
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.']})
此 issue 中的以下引述解释了您在问题的第一部分中描述的行为。
This is by design. Primarily for performance reasons, validation only happens on deserialization (
load
andvalidate
). The data passed todump
is assumed to be valid.
如果您需要验证,例如,您将显式调用 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
版本,您必须明确声明架构为 'strict' 以便自动进行验证。在您的示例中,这可以通过以下方式完成:
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
的最新版本默认为此 'strict' 行为;它还删除了 MarshalResult
/UnmarshalResult
包装器。