Ответ 1
У меня есть пример того, как это сделать в моем блоге на http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/. В основном вы можете улучшить сеанс, чтобы он выбирал из основного или подчиненного на основе запроса по запросу. Один из возможных сбоев в этом подходе состоит в том, что если у вас есть одна транзакция, которая вызывает шесть запросов, вы можете использовать оба подчиненных в одном запросе... но там мы просто пытаемся имитировать функцию Django:)
Немного менее волшебный подход, который также устанавливает область использования более явным образом, я использовал декоратор в виде callables (независимо от того, что они вызываются в Flask), например:
@with_slave
def my_view(...):
# ...
with_slave будет делать что-то вроде этого, предполагая, что у вас есть сеанс и установлены некоторые двигатели:
master = create_engine("some DB")
slave = create_engine("some other DB")
Session = scoped_session(sessionmaker(bind=master))
def with_slave(fn):
def go(*arg, **kw):
s = Session(bind=slave)
return fn(*arg, **kw)
return go
Идея состоит в том, что вызов Session(bind=slave)
вызывает реестр для получения фактического объекта Session для текущего потока, создавая его, если он не существует, однако, поскольку мы передаем аргумент, scoped_session будет утверждать, что сеанс мы здесь совершенно определенно.
Вы указываете его на "подчиненный" для всех последующих SQL. Затем, когда запрос завершен, вы убедитесь, что ваше приложение Flask вызывает Session.remove()
, чтобы удалить реестр для этого потока. Когда реестр будет использоваться в том же потоке, это будет новый сеанс, связанный с "мастером".
Или вариант, вы хотите использовать "ведомый" только для этого вызова, это "безопаснее", поскольку он восстанавливает любое существующее привязку к сеансу:
def with_slave(fn):
def go(*arg, **kw):
s = Session()
oldbind = s.bind
s.bind = slave
try:
return fn(*arg, **kw)
finally:
s.bind = oldbind
return go
Для каждого из этих декораторов вы можете отменить все, связать сессию с "подчиненным", где декоратор помещает его в "master" для операций записи. Если бы вам понадобилось случайное ведомое устройство в этом случае, если у Flask было какое-то "событие начала запроса", вы могли бы установить его в этой точке.