如何为SQLAlchemy模型动态生成棉花糖模式

2024-10-01 17:38:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用SQLAlchemy模型创建一个flaskapi。 我不想为我所有的模型定义一个模式,我不想每次都这样做:

class EntrySchema(ma.ModelSchema):
    class Meta:
        model = Entry

我希望每个模型都有一个模式,这样它可以很容易地转储自己。 创建默认架构并设置Schema.Meta.model不起作用:

^{pr2}$

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


Tags: 模型model定义sqlalchemy架构schema模式meta
3条回答

marshmallow recipes规定了两个可选选项,用于将公共模式选项抛出基类。下面是一个直接从文档中获取的简单示例:

# myproject/schemas.py

from marshmallow_sqlalchemy import ModelSchema

from .db import Session

class BaseSchema(ModelSchema):
    class Meta:
        sqla_session = Session

然后扩展基本模式:

^{pr2}$

这种方法的优点是可以向特定模型添加更多的反序列化

链接文档上的更多示例和配方

您可以创建一个类装饰器,将Schema添加到模型中:

def add_schema(cls):
    class Schema(ma.ModelSchema):
        class Meta:
            model = cls
    cls.Schema = Schema
    return cls

然后呢

^{pr2}$

模式将作为类属性Entry.Schema提供。在

最初的尝试失败的原因是棉花糖Schema类是使用custom metaclass构造的,它检查通过执行类主体和does its thing创建的命名空间。修改已经构造的类时,为时已晚。在

如果您不熟悉Python中的元类,请在language reference中了解它们。他们是一个工具,允许伟大的事情和伟大的滥用。在

摘自棉花糖sqlalchemy recipes:

"Automatically Generating Schemas For SQLAlchemy Models It can be tedious to implement a large number of schemas if not overriding any of the generated fields as detailed above. SQLAlchemy has a hook that can be used to trigger the creation of the schemas, assigning them to the SQLAlchemy model property ".

我的例子是使用烧瓶炼金术和棉花糖炼金术:

from flask_sqlalchemy import SQLAlchemy
from marshmallow_sqlalchemy import ModelConversionError, ModelSchema
from sqlalchemy import event
from sqlalchemy.orm import mapper


db = SQLAlchemy()


def setup_schema(Base, session):
    # Create a function which incorporates the Base and session information
    def setup_schema_fn():
        for class_ in Base._decl_class_registry.values():
            if hasattr(class_, "__tablename__"):
                if class_.__name__.endswith("Schema"):
                    raise ModelConversionError(
                        "For safety, setup_schema can not be used when a"
                        "Model class ends with 'Schema'"
                    )

                class Meta(object):
                    model = class_
                    sqla_session = session

                schema_class_name = "%sSchema" % class_.__name__

                schema_class = type(schema_class_name, (ModelSchema,), {"Meta": Meta})

                setattr(class_, "Schema", schema_class)

    return setup_schema_fn


event.listen(mapper, "after_configured", setup_schema(db.Model, db.session))

食谱中还有一个例子:

https://marshmallow-sqlalchemy.readthedocs.io/en/latest/recipes.html#automatically-generating-schemas-for-sqlalchemy-models

相关问题 更多 >

    热门问题