Eu tenho um exemplo de como fazer isso no meu blog em http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/ . Basicamente, você pode aprimorar a Sessão para que ela escolha entre mestre ou escravo em uma base de consulta por consulta. Uma falha potencial com essa abordagem é que, se você tiver uma transação que chama seis consultas, pode acabar usando os dois escravos em uma solicitação .... mas estamos apenas tentando imitar o recurso do Django :)
Uma abordagem um pouco menos mágica que também estabelece o escopo de uso mais explicitamente que eu usei é um decorador em view callables (o que quer que eles sejam chamados no Flask), assim:
@with_slave
def my_view(...):
# ...
with_slave faria algo assim, supondo que você tenha uma sessão e alguns mecanismos configurados:
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
A ideia é que chamar
Session(bind=slave)
invoca o registro para obter o objeto Session real para o thread atual, criando-o se ele não existir - no entanto, como estamos passando um argumento, scoped_session afirmará que a Session que estamos fazendo aqui é definitivamente nova. Você aponta para o "escravo" para todos os SQLs subsequentes. Então, quando a solicitação terminar, você garantirá que seu aplicativo Flask esteja chamando
Session.remove()
para limpar o registro para esse segmento. Quando o registro for usado novamente no mesmo thread, será uma nova sessão vinculada de volta ao "mestre". Ou uma variante, você deseja usar o "escravo" apenas para essa chamada, isso é "mais seguro" pois restaura qualquer ligação existente de volta à Sessão:
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
Para cada um desses decoradores você pode reverter as coisas, fazer com que a Session seja vinculada a um "slave" onde o decorador o coloca em "master" para operações de gravação. Se você quisesse um escravo aleatório nesse caso, se o Flask tivesse algum tipo de evento "request begin", você poderia configurá-lo nesse ponto.