2012-04-18 17 views
24

Ich habe den Eindruck, dass Datenbankaufrufe über SQLAlchemy blockieren und nicht für andere Zwecke als synchronen Code geeignet sind. Habe ich Recht (ich hoffe ich bin es nicht!) Oder gibt es eine Möglichkeit, es als nicht blockierend zu konfigurieren?Kann SQLAlchemy als nicht blockierend konfiguriert werden?

+1

Kurze Antwort, nein. Es sind die Datenbankbibliotheken, die blockieren, nicht SQLalchemy selbst. Nichts hält dich davon ab, DB-Sachen in einem separaten Thread zu tun. – AdamKG

+2

@AdamKG Dies sollte wahrscheinlich eine Antwort sein, kein Kommentar! :-) – Matty

Antwort

24

Sie können SQLA in einem nicht blockierenden Stil mit gevent verwenden. Hier ist ein Beispiel unter Verwendung von psycopg2, mit psycopg2 den coroutine support:

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

ich auch habe gehört, Leute die gleiche Idee mit pymysql verwenden. Da pymysql in reinem Python ist und die Sockets-Bibliothek verwendet, pattet gevent die Socket-Bibliothek asynchron.

+0

Ausgezeichnet! Vielen Dank. Gibt es irgendwelche Einschränkungen, die ich beachten sollte (die nicht in der Dokumentation erscheinen), wenn ich sie auf diese Weise benutze? – Matty

+1

nicht sicher. Ich fand es schien besser zu funktionieren mit NullPool, die das Pooling deaktiviert. Sonst ließ es etwas hängen. Also vielleicht vorsichtig mit beginnen mit .. – zzzeek

+3

@zzzeek Ihre hängt möglicherweise von SQLAlchemy's Standard-Pool (QueuePool) mit nicht-Affe-Patched Threading. Wenden Sie entweder gevent's affe patch an oder erstellen Sie eine grüne Version von QueuePool für das Beispiel unter https://groups.google.com/forum/#!msg/gevent/533wzrnL0Fs/ijL34u5prYIJ. Das hat das gleiche Verhalten repariert, als ich es hatte. – CryingCyclops

6

Werfen Sie einen Blick auf Tornado, da sie ein paar saubere blockierungsfreie Bibliotheken haben, besonders tornado.gen.

Wir verwenden das zusammen mit Momoko, eine nicht blockierende psycopg Wrapper-Bibliothek für Tornado. Es war bisher großartig. Der einzige Nachteil ist, dass Sie alle Modellobjekte, die Ihnen SQLAlchemy zur Verfügung stellt, verlieren. Leistung ist jedoch unwirklich.

+0

Ich habe mir Tornado angeschaut und ich kann diesen Weg gehen. Vielleicht sollte ich etwas Demo-Code schreiben, um dies zu testen, aber wenn der psycopg-Treiber Async-Datenbankaufrufe unterstützt (was er anscheinend tut), dann wäre es möglich, nicht blockierende DB-Aufrufe mit SQLAlchemy zu machen. – Matty

+0

@Matty Gute Idee, ich würde gerne hören, wie Sie damit gehen. Eines der Hauptprobleme, von denen ich mir vorstelle, dass Sie mit SQLAlchemy konfrontiert werden, ist nicht genau zu wissen, wann ein blockierender Anruf getätigt wird. Natürlich könntest du immer tief in den Code eintauchen, um herauszufinden, wann mein Bauch sagt, dass das eine Menge Arbeit sein wird. – kuhnza

+0

@Kahunza Nach einem kurzen Blick auf die Dokumentation für psycopg2 erscheint ein Argument, das in die Verbindungszeichenfolge aufgenommen werden kann, die an die 'create_engine()' -Funktion von SQLAlchemy übergeben wird. Vielleicht wird einer der Betreuer reinhören oder ich werde auf ihrer Liste fragen. Prost! – Matty

1

Ohne die Hilfe von Greenlet, ist die Antwort nein, im Zusammenhang mit asyncio.

Es ist jedoch möglich, nur einen Teil von SQLAlchemy in asyncio zu verwenden. Finden Sie ein Beispiel in der GINO project, wo wir nur SQLAlchemy Kern ohne Engine und vollständige Ausführung Kontext verwendet, um eine einfache ORM in asyncio.

Verwandte Themen