Tengo un ejemplo de cómo hacer esto en mi blog en http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/. Básicamente puede mejorar la sesión para que elija entre maestro o esclavo consulta por consulta. Un problema potencial con ese enfoque es que si tiene una transacción que llama a seis consultas, puede terminar usando ambos esclavos en una solicitud ... pero ahí estamos tratando de imitar la función de Django :)
A ligeramente enfoque menos mágica que también establece el alcance del uso de manera más explícita que he usado es un decorador de vista callables (como se llamen en el frasco), así:
@with_slave
def my_view(...):
# ...
with_slave haría algo como esto, suponiendo que tiene una sesión y algunos motores 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
La idea es que llamar al Session(bind=slave)
invoca el registro para obtener el objeto de sesión actual para el hilo actual, crearlo si no existe; sin embargo, dado que estamos pasando un argumento, scoped_session afirmará que la sesión que estamos hacer aquí es definitivamente nuevo.
Lo señala en el "esclavo" para todos los SQL posteriores. Luego, cuando la solicitud finalice, se aseguraría de que su aplicación Flask llame al Session.remove()
para borrar el registro de esa cadena. Cuando el registro se usa a continuación en el mismo hilo, será una nueva sesión vinculada al "maestro".
o una variante, que desea utilizar el "esclavo" sólo por esa llamada, esto es "más seguro", ya que restaura cualquier vinculación existente La vuelta a la Sesión:
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 uno de estos decoradores puede invertir las cosas, haga que la sesión se vincule a un "esclavo" donde el decorador lo pone en "maestro" para las operaciones de escritura. Si quisieras un esclavo aleatorio en ese caso, si Flask tuviera algún tipo de evento de "solicitud para comenzar", podrías configurarlo en ese punto.
Thnx zzzeek Esto ayuda mucho. Felicitaciones a todo el trabajo increíble en sqlalchemy. –
¡Comentario de Rad, ejemplos de código geniales también! Sería bueno si sqlalchemy tuviera alguna manera de hacer análisis de consultas y enrutar automáticamente, pero en un mundo donde una consulta puede causar una tabla tmp u otra operación de escritura como resultado de lo que presumiblemente normalmente solo sería leído, requeriría algo así como solicitar el plan de consulta desde el back-end antes de enviar la consulta y sería más complicado de lo que sería en la mayoría de los casos. –
tenemos la opción de "análisis de consultas", aunque requiere que usted mismo escriba el análisis. El sistema de fragmentación horizontal ilustra un ejemplo de este tipo de técnica, consulte http://docs.sqlalchemy.org/en/rel_0_7/orm/extensions/horizontal_shard.html. – zzzeek