我编写了一个Flask应用程序,该应用程序使用在Apache / mod_wsgi下运行的多个数据库和蓝图。我在理解如何处理多个线程,数据库连接等方面遇到困难。
首先,SQLalchemy文档强烈建议对各个框架使用适当的“胶水”包。在我的情况下,这将是flask-sqlalchemy,但是由于以下几个原因我不能这样做:
Flask应用程序使用的基础SQLAlchemy模型位于需要独立于Flask运行的不同模块中,但是Flask-SQLAlchemy要求模型必须在派生类之上构建,如本摘录自文档:
db = SQLAlchemy(app)
class User(db.Model):
id = db.Column(db.Integer, primary_key=True)
Flask-SQLALchemy似乎仅支持通过
配置的单个数据库连接app.config['SQLALCHEMY_DATABASE_URI'] = '...'
我真的不明白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时,服务器在第二个或第三个请求之后开始超时,我将其解释为在某些竞争条件下线程以某种方式缠结在一起。我不知道出了什么问题,最终将项目恢复到我上面描述的状态。