2016-04-26 8 views
2

Ich habe ein flask webapp in denen Benutzer ihren eigenen MySQL-Datenbanken verbinden können und abfragen, ihre eigenen TabellenFlask-SQLAlchemy - on the fly Verbindungen zu mehreren Datenbanken

Was ist der beste Weg, mehrere Verbindungen zu erstellen (zu unterschiedlichen Datenbanken) mit flask-sqlalchemy. Es scheint, als ob es mit scoped_session und sessionmaker getan werden muss, aber kann nicht meinen Kopf darum herumwickeln.

Auch der zweite Teil der Frage, sobald ich eine Verbindung zu einer MySQL-Datenbank für einen der Benutzer erstellen, wie behalte ich die Verbindung über Anfragen?

Derzeit habe ich die Verbindungszeichenfolge für jeden Benutzer auf den Kolben Session-Variablen und bei jeder neuen Anforderung, erstellen i den Motor und die Verbindung als solche

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 

Dies scheint Super verschwenderisch um den Motor zu schaffen und die Verbindung mit jeder Anfrage - Kann die Verbindung nicht über Anfragen hinweg bestehen?

+1

Ersetzen Sie "rserve" in [diese Frage] (http://stackoverflow.com/questions/28423069/how-can-a-unique-rserve-connection-be-stored-per-session) mit allen Daten, die Sie benötigen In diesem Fall eine SQLAlchemy-Engine. – davidism

+2

Sie würden Flask-SQLAlchemy nicht verwenden, da dies eine bequeme Möglichkeit ist, Ihre eigenen Datenbanken im Voraus zu verwalten. – davidism

Antwort

3

Eine Datenbank

Die Engine ermöglicht es Ihnen, Verbindungspooling zu verwenden. Standardmäßig werden Verbindungen über Anforderungen hinweg beibehalten. Die grundlegende Verwendung (ohne Phantasie Dinge wie scoped_session oder sessionmaker) ist wie folgt:

engine = create_engine(...) 

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

Am Anfang dieser, Sie scoped_session und sessionmaker hinzufügen:

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 macht Ihnen das Leben erleichtern, indem alle Bereitstellung dafür:

db = SQLAlchemy(app) 

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

mehrere Datenbanken

Sie können ganz einfach dieses Konzept auf mehrere Datenbanken erweitern:

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

Wenn Sie scoped_session und sessionmaker hinzufügen:

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

Dies wird ein wenig ärgerlich, wenn Sie viele Datenbanken haben, in diesem Fall sollten Sie Schreiben Sie wahrscheinlich eine Registrierungsklasse, um alle Engines und Sitzungen im Auge zu behalten:

Sie müssen eine Art von LRU hinzufügen, damit es keine unbegrenzte Erstellung von Engines gibt.

flask-sqlalchemy unterstützt eine eingeschränkte Form mehrerer Datenbanken, in denen jedes Modell eine Verbindung zu einer anderen Datenbank herstellt. Wenn dies für Sie gilt, lautet die Dokumentation here.

+0

Danke Univerio.Das Problem ist, dass ich nicht mehrere Datenbanken für die App selbst habe - die App-Benutzer, die Verbindungen zu ihren Datenbanken erstellen müssen, um ihre Tabellen abzufragen. Können Sie bitte ein wenig mehr auf "Registry-Klasse, um alle Motoren und Sitzungen zu verfolgen" –

+1

@sarul Siehe bearbeiten. Wenn Sie während der Lebensdauer Ihrer App eine Verbindung zu beliebigen (unbegrenzten) Datenbanken herstellen möchten, müssen Sie eine Art von LRU oben auf der Registrierung hinzufügen, um Speicherlecks in Schach zu halten. – univerio

+0

perfekt. Danke, Univerio für die ausführliche Antwort. –