python - Twisted+SQLAlchemy y la mejor manera de hacerlo
database (4)
En el par de años transcurridos, Alex Gaynor creó https://github.com/alex/alchimia que puede ser un mejor repositorio central para hacer integración con SQLAlchemy y Twisted.
Así que estoy escribiendo otro daemon basado en Twisted. Tendrá una interfaz xmlrpc como de costumbre para que pueda comunicarme fácilmente con ella y hacer que otros procesos intercambien datos según sea necesario.
Este daemon necesita acceder a una base de datos. Hemos estado utilizando SQL Alchemy en lugar de cadenas SQL de codificación dura para nuestros últimos proyectos, los que se hacen principalmente para aplicaciones web en Pylons.
Nos gustaría hacer lo mismo con esta aplicación y volver a usar el código de la biblioteca que hace uso de SQL Alchemy. ¿Entonces lo que hay que hacer? Bueno, desde que esa biblioteca fue escrita para su uso en una aplicación Pylons es el código de estilo de bloqueo directo al que todo el mundo está acostumbrado y todo el no bloqueo es mágicamente manejado por Pylons a través de subprocesos, roscas locales, sesiones de alcance y así en.
Entonces, para Twisted, creo que estoy un poco atascado. Yo podría:
- Simplemente escriba el sql que necesito directamente si es mínimo y use el grupo dbapi en twisted para hacer runInteractions, etc. cuando tenga que pulsar el db.
- Use los objetos y los métodos de bloqueo inherentes en nuestra biblioteca y bloquee de vez en cuando en mi daemon Twisted. Bah.
- Use sAsync que se actualizó por última vez en 2008 y reutilice los modelos que ya hemos definido pero no realmente, y esto no significa que el código de la biblioteca también deba funcionar en Pylons. ¿Eso incluso funciona con la última versión de SQL Alchemy? Quién sabe. Sin embargo, ese proyecto se veía genial: ¿por qué fue aparentemente abandonado?
- Genere un subproceso separado y haga que se ocupe del código de la biblioteca y de todo lo que bloquea, y los resultados se devuelven a mi daemon cuando estén listos como objetos organizados vía YAML sobre xmlrpc.
- Use deferToThread y luego borre los objetos devueltos asegurándose de hacer cargas ansiosas para que tenga todas mis cosas que pueda necesitar. Me parece un poco ugha.
También estoy atascado usando Python 2.5.4 atm así que no tengo 2.6 todavía y no creo que pueda hacer una importación desde el futuro para tener acceso al nuevo y genial módulo de multiprocesamiento. Está bien, aunque supongo que tenemos que lidiar con la comunicación entre procesos bastante bien.
Así que me estoy inclinando por la opción 4 principalmente porque eso evitaría el pecado mortal de la duplicación lógica con la opción 1 y también me mantendría alejado de los hilos.
Sin embargo, mi primer intento será la opción 2 para que todo funcione y luego separar las llamadas al código de la biblioteca, quizás en un proceso separado si parece que hay una buena posibilidad de que algo tarde demasiado en bloquearse. Triste. Quizás una combinación de Stackless Python y Twisted sería interesante aquí.
Alguna mejor idea?
En primer lugar, desafortunadamente solo puedo secundar tu opinión de que twisted y SQLAlchemy no funcionan muy bien. He trabajado un poco con ambos y temería un tanto la complejidad que surgiría al unirlos.
Todas las capas de integración de bases de datos que conozco hasta la fecha usan la capa de integración de subprocesos twisteds, y si quieres evitar eso a toda costa, estás bastante atrapado en el punto 4 de tu lista.
Por otro lado, he visto ejemplos de código de conexión de base de datos usando deferToThread () y amigos que funcionaron muy bien.
De todos modos, algunos indicadores si estaría listo para considerar otros marcos que SQLAlchemy:
Los chicos de DivMod han estado haciendo un trabajo tentativo sobre la integración de bases de datos retorcidas basadas en Storm ORM (google para "storm orm").
Vea este enlace para un ejemplo:
http://divmod.readthedocs.org/en/latest/products/nevow/storm-approach.html
También diríjase al sitio de DivMod y eche un vistazo a las fuentes de su capa Axiom db (probablemente no le sirva directamente, ya que es solo Sqlite, pero sus principios pueden ser útiles).
Hay una rama de tormenta que puede usar con retorcido directamente (internamente, difiere para enhebrar cosas) en el launchpad https://code.launchpad.net/~therve/storm/twisted-integration . Lo he usado muy bien.
Lamentablemente, sqlalchemy es significativamente más complejo en la implementación para auditar el uso asincrónico. Si realmente desea usarlo, recomendaría un enfoque fuera de proceso con una capa de almacenamiento rpc.
alternativamente, si tiene ganas de aventuras y usa postgresql, el último pyscopg2 admite el verdadero uso asincrónico ( https://launchpad.net/txpostgres ), y la fuente de tormentas es bastante simple de hackear ;-)
Incidentalmente, la tormenta que intentó el año pasado puede no haber tenido la extensión C por defecto (ahora está en las últimas versiones), lo que podría explicar sus problemas de velocidad.
Quizás Twistar es lo que estás buscando. Es una implementación de registro activo nativo (aka ORM) para twisted, que funciona en la parte superior de twisted.enterprise.adbapi
.