2012-04-18 20 views
24

Tengo la impresión de que las llamadas a bases de datos a través de SQLAlchemy se bloquearán y no son adecuadas para usar en ningún otro que no sea código síncrono. ¿Estoy en lo correcto (espero no estarlo) o hay una forma de configurarlo para que no sea bloqueante?¿Se puede configurar SQLAlchemy para que no sea bloqueante?

+1

Respuesta corta, no. Son las bibliotecas de bases de datos las que bloquean, no SQLalchemy en sí. Sin embargo, nada le impide hacer cosas de DB en un hilo separado. – AdamKG

+2

@AdamKG Esto probablemente debería ser una respuesta, ¡no un comentario! :-) – Matty

Respuesta

24

Puede usar SQLA en un estilo sin bloqueo usando gevent. Aquí hay un ejemplo usando psycopg2, usando de coroutine support psycopg2: gente

https://bitbucket.org/zzzeek/green_sqla/

También he oído utilizan la misma idea con pymysql. Como pymysql está en Python puro y usa la biblioteca de sockets, gevent remueve la biblioteca de socket para que sea asíncrona.

+0

¡Excelente! Gracias. ¿Hay alguna advertencia que deba tener en cuenta (que no aparece en los documentos) cuando se usa de esta manera? – Matty

+1

no estoy seguro. Encontré que parecía funcionar mejor usando NullPool, que deshabilita la agrupación. De lo contrario, algo estaba haciendo que se cuelgue. Así que tal vez proceda con precaución para comenzar con ... – zzzeek

+3

@zzzeek Sus cuelgues pueden provenir del grupo predeterminado de SQLAlchemy (QueuePool) usando subprocesos sin parche de monos. Aplica el parche de gevent para el mono o crea una versión verde de QueuePool en el ejemplo en https://groups.google.com/forum/#!msg/gevent/533wzrnL0Fs/ijL34u5prYIJ. Eso solucionó el mismo comportamiento cuando lo tenía. – CryingCyclops

6

Eche un vistazo a Tornado ya que tienen algunas geniales bibliotecas sin bloqueo, particularmente tornado.gen.

Lo usamos junto con Momoko, un psycopg wrapper lib sin bloqueo para Tornado. Ha sido genial hasta ahora. Quizás el único inconveniente es que pierdes todas las cosas del objeto modelo que SQLAlchemy te da. El rendimiento es irreal sin embargo.

+0

He estado mirando a Tornado y es posible que recorra ese camino. Tal vez debería escribir algún código de demostración para probar esto, pero si el controlador psycopg soporta llamadas de base de datos asincrónicas (que aparentemente lo hace), supongo que sería posible hacer llamadas DB no bloqueantes con SQLAlchemy. – Matty

+0

@Matty Buena idea, me encantaría saber cómo te va. Uno de los principales problemas que imagino que alcanzará con SQLAlchemy es no saber exactamente cuándo se realizará una llamada de bloqueo. Por supuesto, siempre puedes hacer una inmersión profunda en el código para descubrir cuándo, por mi instinto, dice que va a ser mucho trabajo. – kuhnza

+0

@Kahunza Después de echar un vistazo rápido a los documentos para psycopg2, parece que hay un argumento que se puede incluir en la cadena de conexión que se pasa a la función 'create_engine()' de SQLAlchemy. Tal vez uno de los mantenedores se acercará o lo haré en su lista. ¡Aclamaciones! – Matty

1

Sin la ayuda de greenlet, la respuesta es no, en el contexto de asyncio.

Sin embargo, es posible usar solo una parte de SQLAlchemy en asyncio. Encontrará un ejemplo en el GINO project, donde solo usamos el núcleo de SQLAlchemy sin motor y el contexto de ejecución completo para crear un ORM simple en asyncio.

Cuestiones relacionadas