当前位置: 首页 > 面试题库 >

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

秦经义
2023-03-14
问题内容

我遇到 了 几种有关如何在Flask-SQLAlchemy中使用香草SQLAlchemy模型的方法。

使用从BaseFlask-SQLAlchemy继承的模型就像一种魅力。

但是我真的很喜欢那种方便的东西…

Job.query.all() # Does not work
db.session.query(Job).all() # Works

因此,我开始着手对此进行研究,并编写了一些代码,但是我受困于此,需要一些帮助才能使它变得更加整洁。

以下块是一个通用定义,不能从任何一个继承。它是从Flask-SQLAlchemy和Vanilla SQLAlchemy导入的,并且应该在某些时候使用。

class VanillaMachine():

    __tablename__ = 'machine'

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

并且有一个工厂接受db.ModelBase返回Machine正确的父对象:

class MachineFactory:

    def __init__(self, *args, **kwargs):
        pass

    def __new__(cls, *args, **kwargs):

        return type('Machine',(object, VanillaMachine, args[0]), VanillaMachine.__dict__.copy())

我很确定该代码有些问题,但是我不确定在哪里。

如果我像这样使用

db = SQLAlchemy()

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

Machine1 = MachineFactory(db.Model)
Machine2 = MachineFactory(Base)

有错误信息

sqlalchemy.exc.ArgumentError: Column object 'id' already assigned to Table 'machine'

可以帮助我以一种不错的,可靠的方式弄清楚这一点吗?

我知道您可以只使用一个函数,将父级作为参数传递给它,VanillaMachine并使用一些if语句,但这太简单了,对吧?:)

编辑:

我遇到的其他方法是

  1. 使用Flask上下文使用Flask-SQLAlchemy模型

    with app.app_context():
    pass
    

    or

    app.app_context().push()

但这对我来说太集中在Flask上,并且不允许清楚地分离模型,使它们独立并适应上下文。

  1. 提供替代基类db = SQLAlchemy(app, model_class=Base),见这里。这可能对我有用,但是到目前为止,我还没有对此进行评估。

问题答案:

我发现了一个很好的解决方案,它受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()


 类似资料:
  • 问题内容: 我已阅读flask-sqlalchemy或sqlalchemy,它们建议将flask-sqlalchemy与flask一起使用。我想遵循这种方法。 但是,我有一个为命令行脚本编写的现有模型,该模型基于sqlalchemy的declarative_base,例如, 我希望仍然可以在此模型中使用命令行脚本,但也希望围绕该模型构建Web应用程序。 有没有办法扩展现有模型,以获得使用flask

  • 问题内容: 我正在尝试构建可在Flask和其他非Flask服务中使用的SQLAlchemy模型。我知道,为了在Flask中使用这些对象,我可以使用Flask- SQLAlchemy模块并构建如下模型: app_builder.py database.py 但是,这样做似乎将模型与使用flask_sqlalchemy绑定在一起。我还有一个服务,我想在不使用flask的情况下使用这些模型。有没有一种方

  • 很多人更倾向于使用 SQLAlchemy 进行数据库操作。在这种情况下,建议您使用 包的而不是模块的方式组织您的应用代码,并将所有的模型放置到一个单独的模块中 (大型应用)。尽管这并非必要,但是这么做将会让程序的结构更加 明晰。 使用 SQLAlchemy 有四种常用的方法,我们在下面列出了这几种方法的基本使用 框架: Flask-SQLAlchemy 扩展 因为 SQLAlchemy 是一个常用

  • 问题内容: 我是flask和sqlalchemy的新手,我只是开始在flask应用程序上工作,现在我正在使用sqlalchemy。我想知道使用flask-sqlalchemy与sqlalchemy是否可以获得任何显着的好处。 问题答案: 主要功能是与Flask应用程序正确集成-它创建并配置引擎,连接和会话,并将其配置为与Flask应用程序一起使用。 此设置非常复杂,因为我们需要创建作用域会话并根据

  • 在Flask Web应用程序中使用原始SQL对数据库执行CRUD操作可能很乏味。 相反,Python工具包SQLAlchemy是一个功能强大的OR映射器,为应用程序开发人员提供了SQL的全部功能和灵活性。 Flask-SQLAlchemy是Flask扩展,它将对SQLAlchemy的支持添加到Flask应用程序中。 什么是ORM(对象关系映射)? 大多数编程语言平台是面向对象的。 另一方面,RDB

  • Flask-SQLAlchemy Flask-SQLAlchemy is an extension for Flask that adds support forSQLAlchemy to your application. It aims to simplify using SQLAlchemywith Flask by providing useful defaults and extra h