mysql - Flask-SQLAlchemy - 即时连接到多个数据库

标签 mysql session flask sqlalchemy flask-sqlalchemy

我有一个 flask webapp,用户可以在其中连接到他们自己的 mysql 数据库并查询他们自己的表

使用 flask-sqlalchemy 创建多个连接(到不同的数据库)的最佳方法是什么。似乎需要使用 scoped_sessionsessionmaker 来完成,但我似乎无法理解它。

也是问题的第二部分,一旦我为其中一个用户创建到 mysql 数据库的连接,我如何在请求之间保持连接?

目前,我将每个用户的连接字符串放在 flask session 变量上,并且在每个新请求中,我都这样创建引擎和连接

engine = create_engine(connection_string, convert_unicode=True)
conn = engine.connect()
db_session = Session(bind=conn) # Session - i create it globally on the __init__ like this Session = scoped_session(sessionmaker()) and import it in the view

## Query using the db_session

创建引擎和与每个请求的连接似乎 super 浪费——不能跨请求保持连接吗?

最佳答案

一个数据库

引擎允许您使用连接池。默认情况下,它将跨请求保持连接。基本用法(没有像 scoped_sessionsessionmaker 这样花哨的东西)是这样的:

engine = create_engine(...)

@app.route(...)
def foo():
    session = Session(bind=engine)
    try:
        session.query(...)
        session.commit()
    finally:
        session.close()
    return ""

在此之上,您可以添加 scoped_sessionsessionmaker:

engine = create_engine(...)
Session = sessionmaker(bind=engine)
session = scoped_session(Session, scopefunc=...)

@app.route(...)
def foo():
    try:
        session.query(...)
        session.commit()
    finally:
        session.close()
    return ""

flask-sqlalchemy 通过提供所有这些让您的生活更轻松:

db = SQLAlchemy(app)

@app.route(...)
def foo():
    db.session.query(...)
    db.session.commit()
    return ""

多个数据库

您可以轻松地将这个概念扩展到多个数据库:

engine1 = create_engine(...)
engine2 = create_engine(...)

@app.route(...)
def foo():
    session = Session(bind=choose_engine_for_user())
    try:
        session.query(...)
        session.commit()
    finally:
        session.close()
    return ""

当您添加 scoped_sessionsessionmaker 时:

engine1 = create_engine(...)
engine2 = create_engine(...)
Session1 = sessionmaker(bind=engine1)
Session2 = sessionmaker(bind=engine2)
session1 = scoped_session(Session1, scopefunc=...)
session2 = scoped_session(Session2, scopefunc=...)

@app.route(...)
def foo():
    session = choose_session_for_user()
    try:
        session.query(...)
        session.commit()
    finally:
        session.close()
    return ""

当你有很多数据库时,这会有点烦人,在这种情况下,你可能应该编写一个注册表类来跟踪所有引擎和 session :

class SessionRegistry(object):
    _registry = {}

    def get(self, url, **kwargs):
        if url not in self._registry:
            engine = create_engine(url, **kwargs)
            Session = session_maker(bind=engine)
            session = scoped_session(Session, scopefunc=...)
            self._registry[url] = session
        return self._registry[url]

registry = SessionRegistry()

@app.route(...)
def foo():
    session = registry.get(...)
    try:
        session.query(...)
        session.commit()
    finally:
        session.close()
    return ""

您需要在其之上添加某种 LRU,这样就不会无限制地创建引擎。

flask-sqlalchemy 支持有限形式的多个数据库,其中每个模型都连接到不同的数据库。如果这适用于您,文档为 here .

关于mysql - Flask-SQLAlchemy - 即时连接到多个数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36877914/

相关文章:

子查询中的 mysql sql_mode=only_full_group_by 不起作用

python - “功能”对象在注册蓝图时没有属性 'name'

MySQL,给定一个列表,从表中选择缺失的行

过程中的 mysql case/when 语句

php - 选择在规范化表中具有多个匹配项的项目

php - 使用数据库生成的列表时传递 PHP 变量而不被看到

javascript - AngularJS 安全 token 与 session

node.js - Req.session undefined with express 4 and Redis store, express-session

python - 发送curl请求时使用bcrypt driver.db进行Eve身份验证错误

python - Flask:不要重定向到 URL