【问题标题】:"Unknown field" after updating to 3.5.0 marshmallow更新到 3.5.0 棉花糖后的“未知字段”
【发布时间】:2020-03-26 11:30:03
【问题描述】:

在我的项目中更新了依赖项

之前

marshmallow-sqlalchemy==0.17.0
marshmallow==3.0.0b6

之后

marshmallow-sqlalchemy==0.21.0
marshmallow==3.5.0

我有这样一个模型(简化):

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class MyModel(Base):
    __tablename__ = 'my_model'

    id = Column(BigInteger, primary_key=True)
    field_name = Column(String)
    password = Column(String)

架构

from marshmallow import fields
from marshmallow_sqlalchemy import (
    ModelSchema,
    field_for,
)
class RegistrarSchema(ModelSchema):
    class Meta:
        model = MyModel

    other_field_name = fields.Function(lambda obj: obj.field_name)
    field_name = field_for(MyModel, 'field_name', load_from='other_field_name')

    password = fields.Method("get_password")

    def get_password(self, obj):
        return decrypt_password(obj)

    def load(self, data, session=None, instance=None, transient=False, *args, **kwargs):
        if 'password' in data:
            password = data['password']
            instance = encrypt_password(password, instance)
        return super(ModelSchema, self).load(
            data, *args, session=session, instance=instance,
            transient=transient, **kwargs
        )

使用这段代码我可以调用

RegistrarSchema.load(data={'other_field_name': 'my_value'}, instance=instance, session=session)

这个值将被保存到我数据库中的 field_name 中。

更新后我失去了这个功能 - 现在我得到了

File "myfile.py", line 116, in load
    transient=transient, **kwargs
  File "/usr/local/lib/python3.7/dist-packages/marshmallow_sqlalchemy/schema.py", line 214, in load
    return super().load(data, **kwargs)
  File "/usr/local/lib/python3.7/dist-packages/marshmallow/schema.py", line 723, in load
    data, many=many, partial=partial, unknown=unknown, postprocess=True
  File "/usr/local/lib/python3.7/dist-packages/marshmallow/schema.py", line 904, in _do_load
    raise exc
marshmallow.exceptions.ValidationError: {'other_field_name': ['Unknown field.']}

更新密码时出现完全相同的错误 -

RegistrarSchema.load(data={'password': 'my_value'}, instance=instance, session=session)

这段代码不是我自己写的,也联系不上是谁写的。

据我所知,第一种情况的目标是提供以两种方式编写的能力 -data={'my_field': 'value'}data={'other_field_name': 'value'}。第一个场景仍在开发新版本,但第二个没有。

如果使用密码 - 目标是通过加密/解密数据使序列化/反序列化更加复杂。

我阅读了更新说明,但没有找到与此问题相关的任何信息,有人可以帮忙吗?

【问题讨论】:

标签: python marshmallow marshmallow-sqlalchemy


【解决方案1】:

在 v3. 中,marshmallow 将默认行为从 EXCLUDE 更改为 RAISE https://marshmallow.readthedocs.io/en/stable/quickstart.html#handling-unknown-fields

您可以通过在 Schema 的 Meta 类中指定 unknown 来恢复旧行为:

class UserSchema(Schema):
    class Meta:
        unknown = EXCLUDE

在实例化时,

schema = UserSchema(unknown=EXCLUDE)

或调用加载时。

UserSchema().load(data, unknown=EXCLUDE)

load 中设置的未知选项值将覆盖实例化时应用的值,该值本身将覆盖 Meta 类中定义的值。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-09-19
    • 2016-01-23
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2021-02-12
    • 1970-01-01
    相关资源
    最近更新 更多