2016-04-26 100 views
2

我有一个flask webapp,用户将能够连接到自己的MySQL数据库和查询自己的表烧瓶SQLAlchemy的 - 在飞行连接到多个数据库

什么是创建多个连接的最佳方式(以不同数据库)使用flask-sqlalchemy。它似乎需要与scoped_sessionsessionmaker完成,但似乎不能包围我的头。

此外,问题的第二部分,一旦我创建一个连接到一个用户的MySQL数据库,我如何坚持连接跨请求?

目前,我把连接字符串的烧瓶会话变量中的每个用户,并在每个新的请求,我创建了发动机和连接,这样

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 

这似乎超级浪费创建发动机和与每个请求连接 - 无法连接跨请求持续?

+1

用你需要的任何数据替换这个问题中的“rserve”(http://stackoverflow.com/questions/28423069/how-can-a-unique-rserve-connection-be-stored-per-session) ,在这种情况下是一个SQLAlchemy引擎。 – davidism

+2

您不会使用Flask-SQLAlchemy,因为这对于提前配置管理自己的数据库非常方便。 – davidism

回答

3

单个数据库

该引擎允许您使用连接池。默认情况下,它将持续连接请求。基本用法(不象​​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 "" 

多个数据库

当您添加 scoped_sessionsessionmaker

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 "" 

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

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

+0

感谢Univerio。问题是我没有为应用程序本身设置多个数据库 - 它的应用程序用户需要创建与其数据库的连接来查询他们的表。请你详细说一下“注册表类以跟踪所有引擎和会话” –

+1

@sarul请参阅编辑。如果您需要在应用程序的生命周期中连接到任意数量的数据库,那么您需要在注册表之上添加某种LRU来检查内存泄漏。 – univerio

+0

完美。感谢Univerio的详细回复。 –