Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Ler escravo, ler-escrever configuração mestre


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.