您好, 欢迎来到 !    登录 | 注册 | | 设为首页 | 收藏本站

如何解决在香草SQLAlchemy和Flask-SQLAlchemy中使用相同模型的方法?

如何解决在香草SQLAlchemy和Flask-SQLAlchemy中使用相同模型的方法?

我发现了一个很好的解决方案,它受sqlAlchemy文档中提到的Factory模式声明性Mixins的启发。

对于复杂的多级继承方案,需要使用另一种方法@declared_attr.cascading

from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy import Column, Integer, String
from sqlalchemy import MetaData

from sqlalchemy.ext.declarative import declarative_base
from flask_sqlalchemy import sqlAlchemy

sqlALCHEMY_DATABASE_URI = 'sqlite:///' + '/tmp/test_app.db'
engine = create_engine(sqlALCHEMY_DATABASE_URI, echo=True)

# for vanilla
Base = declarative_base()

# for Flask (import from app once initialized)
db = sqlAlchemy()


class MachineMixin:

    __tablename__ = 'machine'
    id = Column(Integer, primary_key=True)
    name = Column(String(100))
    status = Column(Integer)


class ModelFactory:

    @staticmethod
    def create(which_model, which_parent):

        if which_parent == 'flask_sqlalchemy':

            parent = db.Model

        elif which_parent == 'pure_sqlalchemy':

            parent = Base

        # Now use type() to interit, fill __dict__ and assign a name
        obj = type(which_model.__name__ + '_' + which_parent,
                    (which_model, parent),
                    {})
        return obj


test_scenario = 'pure_sqlalchemy' # 'flask_sqlalchemy'

Machine = ModelFactory.create(MachineMixin, test_scenario)

if test_scenario == 'flask_sqlalchemy':

    db.Metadata.drop_all(bind=engine)
    db.Metadata.create_all(bind=engine)

elif test_scenario == 'pure_sqlalchemy':

    Base.Metadata.drop_all(bind=engine)
    Base.Metadata.create_all(bind=engine)


Session = sessionmaker(bind=engine)
session = Session()
session.add(Machine(name='Bob', status=1))
session.commit()
Python 2022/1/1 18:31:41 有206人围观

撰写回答


你尚未登录,登录后可以

和开发者交流问题的细节

关注并接收问题和回答的更新提醒

参与内容的编辑和改进,让解决方法与时俱进

请先登录

推荐问题


联系我
置顶