web-dev-qa-db-de.com

Unterstützt Python vorbereitete Anweisungen von MySQL?

Ich habe zuvor an einem PHP - Projekt gearbeitet, bei dem vorbereitete Anweisungen die SELECT-Abfragen um 20% beschleunigten.

Ich frage mich, ob es mit Python funktioniert? Ich kann anscheinend nichts finden, was besagt, dass es NICHT funktioniert.

46
rubayeet

Direkte Antwort, nein nicht.

joshperrys Antwort ist eine gute Erklärung dafür, was es stattdessen tut.

Von Antwort auf eine ähnliche Frage ,

Überprüfen Sie die MySQLdb Package Comments :

Die "Parametrisierung" erfolgt in MySQLdb, indem Zeichenfolgen umgangen werden und diese dann blind in die Abfrage interpoliert werden, anstatt das .__ zu verwenden. MYSQL_STMT-API. Infolgedessen müssen Unicode-Zeichenfolgen zwei .__ durchlaufen. Zwischendarstellungen (codierte Zeichenfolge, codierte codierte Zeichenfolge) bevor sie von der Datenbank empfangen werden.

Die Antwort lautet also: Nein, stimmt nicht.

12
James McMahon

Die meisten Sprachen bieten eine Möglichkeit, generische parametrisierte Anweisungen auszuführen. Python unterscheidet sich nicht. Wenn eine parametrisierte Abfrage verwendet wird, tun dies automatisch Datenbanken, die das Vorbereiten von Anweisungen unterstützen.

In Python sieht eine parametrisierte Abfrage folgendermaßen aus:

cursor.execute("SELECT FROM tablename WHERE fieldname = %s", [value])

Die Art der Parametrisierung kann je nach Treiber unterschiedlich sein. Sie können Ihr Datenbankmodul importieren und dann einen print yourmodule.paramstyle ausführen.

Von PEP-249 :

paramstyle

       String constant stating the type of parameter marker
       formatting expected by the interface. Possible values are
       [2]:

           'qmark'         Question mark style, 
                           e.g. '...WHERE name=?'
           'numeric'       Numeric, positional style, 
                           e.g. '...WHERE name=:1'
           'named'         Named style, 
                           e.g. '...WHERE name=:name'
           'format'        ANSI C printf format codes, 
                           e.g. '...WHERE name=%s'
           'pyformat'      Python extended format codes, 
                           e.g. '...WHERE name=%(name)s'
58
joshperry

Nach einem kurzen Blick durch die Methode execute () eines Cursor-Objekts eines MySQLdb-Pakets (eine Art de-facto-Paket für die Integration mit mysql, denke ich), scheint es (zumindest standardmäßig) nur die Interpolation von Strings und Anführungszeichen und nicht die tatsächlich parametrisierte Abfrage:

if args is not None:
    query = query % db.literal(args)

Wenn dies keine String-Interpolation ist, was ist dann?

Im Falle von Executemany versucht es tatsächlich, das Einfügen/Ersetzen als einzelne Anweisung auszuführen, anstatt es in einer Schleife auszuführen. Es geht darum, keine Magie, wie es scheint. Zumindest nicht in seinem Standardverhalten.

EDIT: Oh, ich habe gerade erkannt, dass der Modulo-Operator überschrieben werden könnte, aber ich hatte das Gefühl, zu betrügen und die Quelle zu betreten. Ich habe jedoch nirgendwo eine überschriebene mod gefunden.

10
shylent

Für Leute, die nur versuchen, dies herauszufinden, [~ # ~] yes [~ # ~] können Sie vorbereitete Anweisungen mit Python und MySQL. Verwenden Sie einfach MySQL Connector/Python von MySQL selbst und instanziieren Sie den rechten Cursor:

https://dev.mysql.com/doc/connector-python/en/index.html

https://dev.mysql.com/doc/connector-python/en/connector-python-api-mysqlcursorprepared.html

5
fromvega

Die von Amit vorgeschlagene SQL-Schnittstelle kann funktionieren, wenn Sie sich nur um die Leistung kümmern. Sie verlieren dann jedoch den Schutz gegen SQL-Injection, den eine native Python-Unterstützung für vorbereitete Anweisungen bieten könnte. Python 3 verfügt über Module, die Unterstützung für PostgreSQL vorbereitete Anweisungen bieten. Für MySQL scheint "oursql" echte Unterstützung für vorbereitete Anweisungen zu bieten (nicht gefälscht wie in den anderen Modulen).

5
user304386

Nicht direkt verwandt, aber diese Antwort auf eine andere Frage bei SO enthält die Syntaxdetails von "Templates". Ich würde sagen, dass die Auto-Escape-Funktion ihr wichtigstes Feature wäre ...

Beachten Sie hinsichtlich der Leistung die Methode executemany für Cursorobjekte. Es bündelt eine Reihe von Abfragen und führt sie alle auf einmal aus, wodurch do zu einer besseren Leistung führt.

1
Michał Marczyk

Es gibt eine Lösung!

Sie können sie verwenden, wenn Sie sie in einer gespeicherten Prozedur auf dem Server ablegen und von Python so aufrufen ... 

cursor.callproc(Procedurename, args)

Hier ist ein kleines Tutorial zu gespeicherten Prozeduren in MySQL und Python.

http://www.mysqltutorial.org/calling-mysql-stored-procedures-python/

0
whoopididoo