我有一个flask webapp
,用户可以连接到自己的mysql数据库并查询自己的表
使用flask-sqlalchemy创建多个连接(到不同数据库)的最佳方法是什么。似乎需要使用scoped_session
和sessionmaker
完成,但似乎无法绕过它。
问题的第二部分,一旦我为其中一个用户创建了与mysql数据库的连接,我如何在请求之间保持连接?
目前,我将每个用户的连接字符串放在flask会话变量上,并且在每个新请求中,我都会创建引擎和连接
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
创建引擎以及与每个请求的连接似乎非常浪费 - 无法在请求之间保持连接?
答案 0 :(得分:4)
引擎允许您使用连接池。默认情况下,它将在请求之间保持连接。基本用法(没有像scoped_session
或sessionmaker
这样的花哨的东西)是这样的:
engine = create_engine(...)
@app.route(...)
def foo():
session = Session(bind=engine)
try:
session.query(...)
session.commit()
finally:
session.close()
return ""
除此之外,您还可以添加scoped_session
和sessionmaker
:
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_session
和sessionmaker
时:
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 ""
当你有很多数据库时,这会有点烦人,在这种情况下你应该编写一个注册表类来跟踪所有的引擎和会话:
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。