Příklad, jak to udělat, mám na svém blogu na adrese http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/ . V zásadě můžete vylepšit relaci tak, aby si vybrala z hlavní nebo podřízené na základě dotazu po dotazu. Jedním z potenciálních problémů s tímto přístupem je, že pokud máte jednu transakci, která volá šest dotazů, můžete skončit používáním obou otroků v jednom požadavku....ale tam se jen snažíme napodobit Djangovu vlastnost :)
O něco méně magický přístup, který také jasněji určuje rozsah použití, který jsem použil, je dekorátor na zobrazení callables (ať už se v baňce nazývají jakkoli), takto:
@with_slave
def my_view(...):
# ...
with_slave by udělal něco takového, za předpokladu, že máte nastavenou relaci a nějaké motory:
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
Cílem je volání Session(bind=slave)
vyvolá registr, aby se dostal ke skutečnému objektu Session pro aktuální vlákno, a vytvoří jej, pokud neexistuje - ale protože předáváme argument, scoped_session bude tvrdit, že Session, kterou zde vytváříme, je rozhodně zcela nová.
Namíříte jej na "slave" pro všechny následující SQL. Až bude požadavek u konce, měli byste se ujistit, že aplikace Flask volá Session.remove()
vymazat registr pro toto vlákno. Při příštím použití registru ve stejném vláknu se bude jednat o novou relaci vázanou zpět na "master".
Nebo varianta, kterou chcete použít „slave“ pouze pro toto volání, je „bezpečnější“ v tom, že obnovuje jakékoli existující spojení zpět na relaci:
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
U každého z těchto dekoratérů můžete věci zvrátit, nechat relaci svázat s „otrokem“, kde jej dekoratér nastaví na „master“ pro operace zápisu. Pokud byste v tomto případě chtěli náhodného otroka, pokud měl Flask nějakou událost "požadavek začít", můžete ji v tomto okamžiku nastavit.