私はhttp://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/で私のブログ上でこれを行う方法の例を持っています。基本的には、Sessionを拡張して、クエリごとにマスタまたはスレーブから選択することができます。このアプローチの潜在的な不具合の1つは、6つのクエリを呼び出す1つのトランザクションがある場合、1つのリクエストで両方のスレーブを使用することになるかもしれないということです。また、私が使用した、より明示的に利用範囲を確立し、わずかに少ない魔法のアプローチは、このようなビューを呼び出し可能(それらがフラスコ内で呼び出されているものは何でも)、上のデコレータです:
@with_slave
def my_view(...):
# ...
with_slaveはこのような何かをするだろう、あなたがセッションを持っていると仮定して、いくつかのエンジンが設定:
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
考えてみるとSession(bind=slave)
を呼び出すとレジストリを呼び出して現在のスレッドの実際のSessionオブジェクトを取得し、存在しない場合は作成しますが、引数を渡すので、scoped_sessionはセッションをアサートしますここに作ることは間違いなく新しいことです。
後続のすべてのSQLの「スレーブ」を指します。その後、要求が終了したらFlaskアプリがSession.remove()
を呼び出してそのスレッドのレジストリをクリアするようにします。同じスレッド上でレジストリが次に使用されると、それは「マスター」にバインドされた新しいセッションになります。これらのデコレータのそれぞれについて
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
:
または変異体は、あなただけでは、コールのための「スレーブ」を使用する場合、これは、それが戻ってセッションへの既存のバインドを復元していることで、「より安全」でありますあなたは物事を逆転させることができます。セッションは、デコレータが書き込み操作のために「マスター」に置く「スレーブ」にバインドされます。その場合にランダムスレーブが必要だった場合、Flaskに何らかの "要求開始"イベントがあった場合は、その時点で設定することができます。
のthnxが、これは多くのことができますzzzeek。 sqlalchemyのすばらしい仕事の功績。 –
Radのコメント、素晴らしいコード例もあります! sqlalchemyがクエリ分析とルートを自動的に行う方法があればいいですが、クエリがtmpテーブルやその他の書き込み操作の原因となるかもしれない世界では、おそらく通常は読み取り専用のものが要求されますクエリを送信する前のバックエンドからのクエリプランは、ほとんどの場合価値があるよりも面倒です。 –
私たちは "クエリ分析"オプションを持っていますが、あなた自身で分析を書く必要があります。水平シャーディングシステムは、この種の技術の例を示しています.http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/horizontal_shard.htmlを参照してください。 – zzzeek