Jeg har et eksempel på, hvordan man gør dette på min blog på http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/ . Grundlæggende kan du forbedre sessionen, så den vælger mellem master eller slave på en forespørgsel-for-forespørgsel basis. En potentiel fejl med den tilgang er, at hvis du har en transaktion, der kalder seks forespørgsler, kan du ende med at bruge begge slaver i én anmodning....men der prøver vi bare at efterligne Djangos funktion :)
En lidt mindre magisk tilgang, der også fastlægger anvendelsesomfanget mere eksplicit, jeg har brugt, er en dekoratør på view callables (hvad end de hedder i Flask), som denne:
@with_slave
def my_view(...):
# ...
with_slave ville gøre noget som dette, forudsat at du har en session og nogle motorer sat op:
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
Ideen er at kalde Session(bind=slave)
kalder registreringsdatabasen for at komme til det faktiske sessionsobjekt for den aktuelle tråd, og opretter det, hvis det ikke eksisterer - men da vi sender et argument, vil scoped_session hævde, at den session, vi laver her, absolut er helt ny.
Du peger den på "slaven" for al efterfølgende SQL. Så, når anmodningen er overstået, vil du sikre dig, at din Flask-app kalder Session.remove()
for at rydde registreringsdatabasen for den tråd. Når registreringsdatabasen næste gang bruges på den samme tråd, vil det være en ny session bundet tilbage til "masteren".
Eller en variant, du vil bruge "slaven" kun for det opkald, dette er "sikrere" ved, at det gendanner enhver eksisterende binding tilbage til 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
For hver af disse dekoratører kan du vende tingene om, få sessionen til at blive bundet til en "slave", hvor dekoratøren sætter den på "master" til skriveoperationer. Hvis du ville have en tilfældig slave i det tilfælde, hvis Flask havde en form for "request start"-begivenhed, kunne du konfigurere den på det tidspunkt.