【问题标题】:How to use schema.dump feature with a plucked data_key?如何将 schema.dump 功能与采摘的 data_key 一起使用?
【发布时间】:2020-04-03 21:23:57
【问题描述】:

我正在使用 Flask-Marshmallow 和 Flask-SQLAlchemy 将数据转储到 API。

我在 API 中有一个选项可以转储响应中的特定字段:

schema = UserSchema()
schema.dump(data, only=fields)

如果使用 data_key 功能提取其中一个字段名称,我会得到一个错误:

ValueError: Invalid fields for <UserSchema()>: {'account_name'}.

澄清:要正确过滤此字段,客户端必须通过 accountname 以返回 account_name。这是不可取的,因为客户端没有暴露于内部实现。

示例代码:

class User(db.Model):
    __tablename__ = 'users'
    user_id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String)

    account = db.relationship('Account', backref='user')


class Account(db.Model):
    __tablename__ = 'accounts'
    account_id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer)
    accountname = db.Column(db.String)


class UserSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = User
        include_fk = True
        sqla_session = db.session

    account = ma.Pluck('AccountSchema', 'accountname', data_key='account_name')


class AccountSchema(ma.SQLAlchemyAutoSchema):
    class Meta:
        model = Account
        include_fk = True
        sqla_session = db.session

有没有什么技巧可以根据 data_key 让 Marshmallow 转储?

更新:我目前正在通过使用映射器装饰控制器功能以蛮力方法解决此问题。不过,要是棉花糖能搞定就好了?

【问题讨论】:

    标签: marshmallow


    【解决方案1】:

    我想这里的问题是您将用户数据(来自客户端的键名)传递到了对象世界(转储)的方法中,这并不意味着。

    即使不涉及Pluck 字段,我认为它也不会起作用,不是吗?

    您需要一个将用户字段选择转换为对象世界(字段名称)的层。

    这是您正在使用的映射。也许您可以通过自省模式来自动生成映射。这可以在基础架构类中完成。

    【讨论】:

    • 架构是 ma.SQLAlchemySchema 的子类。这会自省到数据库并返回模型中的所有字段。 API 在获取数据后调用 schema.dump 方法。客户端在响应中看到 account_name,但客户端无法使用 account_name 过滤到该字段。他们必须通过 accountname 作为过滤器来返回 account_name。这是不希望的,因为内部对象模型未在 API 中公开。这有意义吗?
    • 当然。您需要一个层来将客户端字段名称转换为对象/数据库字段名称。 lib 无法为您执行此操作。您可以手动定义映射。或者,也许您可​​以自省模式以从字段名称和 data_key 属性构建映射。
    猜你喜欢
    • 2017-07-20
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 2017-01-16
    • 2016-07-03
    • 1970-01-01
    • 2018-03-15
    相关资源
    最近更新 更多