Skip to content

Commit f23fdb9

Browse files
committed
Merge pull request pallets-eco#40 from EnTeQuAk/multidb-sessions
Added support for multiple databases for the session.
2 parents b0e8d6a + 828dbf3 commit f23fdb9

File tree

2 files changed

+26
-3
lines changed

2 files changed

+26
-3
lines changed

flaskext/sqlalchemy.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,11 +184,12 @@ def after_rollback(self, session):
184184
class _SignallingSession(Session):
185185

186186
def __init__(self, db, autocommit=False, autoflush=False, **options):
187-
Session.__init__(self, autocommit=autocommit, autoflush=autoflush,
188-
extension=db.session_extensions,
189-
bind=db.engine, **options)
190187
self.app = db.get_app()
191188
self._model_changes = {}
189+
Session.__init__(self, autocommit=autocommit, autoflush=autoflush,
190+
extension=db.session_extensions,
191+
bind=db.engine,
192+
binds=db.get_binds(self.app), **options)
192193

193194
def get_bind(self, mapper, clause=None):
194195
# mapper is None if someone tries to just get a connection
@@ -756,6 +757,20 @@ def get_tables_for_bind(self, bind=None):
756757
result.append(table)
757758
return result
758759

760+
def get_binds(self, app=None):
761+
"""Returns a dictionary with a table->engine mapping.
762+
763+
This is suitable for use of sessionmaker(binds=db.get_binds(app)).
764+
"""
765+
app = self.get_app(app)
766+
binds = [None] + list(app.config.get('SQLALCHEMY_BINDS') or ())
767+
retval = {}
768+
for bind in binds:
769+
engine = self.get_engine(app, bind)
770+
tables = self.get_tables_for_bind(bind)
771+
retval.update(dict((table, engine) for table in tables))
772+
return retval
773+
759774
def _execute_for_all_tables(self, app, bind, operation):
760775
app = self.get_app(app)
761776

test_sqlalchemy.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ def _remove_files():
204204
atexit.register(_remove_files)
205205

206206
app = flask.Flask(__name__)
207+
app.config['SQLALCHEMY_ENGINE'] = 'sqlite://'
207208
app.config['SQLALCHEMY_BINDS'] = {
208209
'foo': 'sqlite:///' + db1,
209210
'bar': 'sqlite:///' + db2
@@ -254,6 +255,13 @@ class Baz(db.Model):
254255
self.assertEqual(len(metadata.tables), 1)
255256
self.assert_('baz' in metadata.tables)
256257

258+
# do the session have the right binds set?
259+
self.assertEqual(db.get_binds(app), {
260+
Foo.__table__: db.get_engine(app, 'foo'),
261+
Bar.__table__: db.get_engine(app, 'bar'),
262+
Baz.__table__: db.get_engine(app, None)
263+
})
264+
257265

258266
class DefaultQueryClassTestCase(unittest.TestCase):
259267

0 commit comments

Comments
 (0)