如何为SQLAlchemy模型动态生成marshmallow模式

Jas*_*per 8 python sqlalchemy flask marshmallow

我正在使用SQLAlchemy模型创建Flask API.我不想为每个模型定义一个模式,我不想每次都这样做:

class EntrySchema(ma.ModelSchema):
    class Meta:
        model = Entry
Run Code Online (Sandbox Code Playgroud)

我希望每个模型都有一个模式,因此它可以轻松地自行转储.创建默认架构并设置Schema.Meta.model不起作用:

class Entry(db.Model):
    __tablename__ = 'entries'

    id = db.Column(db.Integer, primary_key=True)
    started_at = db.Column(db.DateTime)
    ended_at = db.Column(db.DateTime)
    description = db.Column(db.Text())

    def __init__(self, data):
        for key in data:
            setattr(self, key, data[key])

        self.Schema = Schema
        self.Schema.Meta.model = self.__class__

    def dump(self):
        schema = self.Schema()
        result = schema.dump(self)
        return result


class Schema(ma.ModelSchema):
    class Meta:
        pass
Run Code Online (Sandbox Code Playgroud)

为什么覆盖模型的泛型Schema与声明模型的Schema不同?

Ilj*_*ilä 6

您可以创建一个类装饰器来添加Schema模型:

def add_schema(cls):
    class Schema(ma.ModelSchema):
        class Meta:
            model = cls
    cls.Schema = Schema
    return cls
Run Code Online (Sandbox Code Playgroud)

然后

@add_schema
class Entry(db.Model):
    ...
Run Code Online (Sandbox Code Playgroud)

架构将作为class属性提供Entry.Schema.

原始尝试失败的原因是Schema使用自定义元类构造marshmallow ,该元类检查从执行类主体创建的命名空间并执行其操作.修改已构造的类时,为时已晚.

如果您不熟悉Python中的元类,请在语言参考中阅读它们.它们是一种可以实现伟大事物和极大误用的工具.