Jag har ett exempel på hur man gör detta på min blogg på http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/ . I grund och botten kan du förbättra sessionen så att den kan välja mellan master eller slav på en fråga-för-fråga-basis. En potentiell glitch med det tillvägagångssättet är att om du har en transaktion som anropar sex frågor, kan du sluta använda båda slavarna i en begäran....men där försöker vi bara imitera Djangos funktion :)
Ett lite mindre magiskt tillvägagångssätt som också fastställer användningsomfånget mer explicit som jag har använt är en dekoratör på view callables (vad de än heter i Flask), så här:
@with_slave
def my_view(...):
# ...
with_slave skulle göra något så här, förutsatt att du har en session och vissa motorer inställda:
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
Tanken är att anropa Session(bind=slave)
anropar registret för att komma till det faktiska sessionsobjektet för den aktuella tråden och skapar det om det inte finns - men eftersom vi skickar ett argument kommer scoped_session att hävda att sessionen vi gör här definitivt är helt ny.
Du pekar den på "slaven" för all efterföljande SQL. Sedan, när begäran är över, ser du till att din Flask-app anropar Session.remove()
för att rensa ut registret för den tråden. När registret nästa gång används på samma tråd, kommer det att vara en ny session kopplad tillbaka till "master".
Eller en variant, du vill använda "slaven" bara för det anropet, detta är "säkrare" genom att det återställer eventuell befintlig bindning tillbaka till sessionen:
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
För var och en av dessa dekoratörer kan du vända på saker, låt sessionen bindas till en "slav" där dekoratören sätter den på "master" för skrivoperationer. Om du ville ha en slumpmässig slav i det fallet, om Flask hade någon form av "begäran börja"-händelse kunde du ställa in det vid den tidpunkten.