如何正确集成SQLAlchemy,Flask,蓝图和多个数据库?

时间:2019-12-17 08:19:54

标签: python flask sqlalchemy

我编写了一个Flask应用程序,该应用程序使用在Apache / mod_wsgi下运行的多个数据库和蓝图。我在理解如何处理多个线程,数据库连接等方面遇到困难。

首先,SQLalchemy文档强烈建议对各个框架使用适当的“胶水”包。在我的情况下,这将是flask-sqlalchemy,但是由于以下几个原因我不能这样做:

  1. Flask应用程序使用的基础SQLAlchemy模型位于需要独立于Flask运行的不同模块中,但是Flask-SQLAlchemy要求模型必须在派生类之上构建,如本摘录自文档:

    db = SQLAlchemy(app)
    
    class User(db.Model):
        id = db.Column(db.Integer, primary_key=True)
    
  2. Flask-SQLALchemy似乎仅支持通过

    配置的单个数据库连接
    app.config['SQLALCHEMY_DATABASE_URI'] = '...'
    
  3. 我真的不明白Flask-SQLAlchemy的功能,因为如果我这样做了,我可能不会写这个。小节“启蒙之路”列出了一些琐碎的杂文,IMO并没有为依赖附加软件包辩解。

我的应用程序使用了几个“中央” MSSQL数据库和一堆MySQL数据库,这些数据库通常特定于每个蓝图的任务。每个蓝图都驻留在其自己的模块(文件)中,并从该模块中导入到主应用程序中。

这就是我在做什么。我在主应用程序中使用的中央数据库(也导入了蓝图):

pd_engine = create_engine(app.config['URI_PDB'])
fd_engine = create_engine(app.config['URI_FDB'])
pdSession = scoped_session(sessionmaker(pd_engine))
fdSession = scoped_session(sessionmaker(fd_engine))

@app.before_request
def open_dbs():
    flask.g.pdSession = pdSession
    flask.g.fdSession = fdSession

...以及请求处理程序(在蓝图中):

blp = flask.Blueprint(...)

@blp.route('/'):
def index():
    pdb = flask.g.pdSession()
    pdb.query()
    pdb.close() # or should this be pdb.remove()?

在我看来,这听起来不错。现在到每个蓝图数据库:

# file oneblueprint.py

engine = create_engine("mysql://this_bluprint/db")
Session scoped_session(sessionmaker(engine))

@blp.route('/specific/')
def specific():
    db = Session()
    db.query()
    db.close()

这有效,但似乎不正确。 (作用域)会话不应该在“中心”位置进行吗?我可以在主应用程序中进行会话,然后将它们附加到flask.g.whatever(就像我对dbSession和fdSession所做的那样),但是我想在每个需要它们的蓝图中隔离有关所需GB连接的知识。请注意,有一些“本地”数据库供多个蓝图使用。

当前,此设置有效,但仅出于偶然。最近,我尝试重构一些与数据库相关的代码。在单线程环境(内置的Flask开发服务器)中,一切正常。但是,当我将其部署到Apache时,服务器在第二个或第三个请求之后开始超时,我将其解释为在某些竞争条件下线程以某种方式缠结在一起。我不知道出了什么问题,最终将项目恢复到我上面描述的状态。

0 个答案:

没有答案