2012-07-06 1 views
7

Come posso sfuggire l'input a un db MySQL in Python3? Sto usando PyMySQL e funziona bene, ma quando provo a fare qualcosa di simile:Come posso sfuggire l'input a un db MySQL in Python3?

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` = '{}'".format(request[1])) 

non funzionerà se la stringa ha ' o ". Ho anche provato:

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` = %s",request[1]) 

Il problema di questo è che la biblioteca (PyMySQL) utilizza la sintassi di formattazione per python2.X, %, che non funziona più. Ho trovato anche questo possibile soluzione

conn.escape_string() 

in here, ma io non so dove per aggiungere questo codice. Questo è tutto quello che ho:

import pymysql 
import sys 
conn = pymysql.connect(host = "localhost", 
      user = "test", 
      passwd = "", 
      db  = "test") 
cursor = conn.cursor() 
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` = {}".format(request[1])) 

result = cursor.fetchall() 

cursor.close() 
conn.close() 

Edit: ho risolto! In PyMySQL il modo giusto è come questo:

import pymysql 
import sys 
conn = pymysql.connect(host="localhost", 
      user="test", 
      passwd="", 
      db="test") 
cursor = conn.cursor() 
text = conn.escape(request[1]) 
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` = {}".format(text)) 

cursor.close() 
conn.close() 

dove la linea text = conn.escape(request[1]) è ciò che sfugge il codice. Trovato all'interno del codice PyMySQL. Lì, request[1] è l'input.

+1

Freddo. Dovresti pubblicare la seconda metà della tua domanda come risposta, però. Puoi accettare la tua risposta. – Grilse

+0

Oops, non ho visto quel pulsante prima. – user1460016

+0

Se risolto, quindi contrassegna la tua domanda come accettata. :-) – Jocelyn

risposta

6

Risolto. In PyMySQL il modo giusto è come questo:

import pymysql 
import sys 
conn = pymysql.connect(host="localhost", 
      user="test", 
      passwd="", 
      db="test") 
cursor = conn.cursor() 
text = conn.escape(request[1]) 
cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` = {}".format(text)) 

cursor.close() 
conn.close() 

dove la linea text = conn.escape(request[1]) è ciò che sfugge il codice. Trovato all'interno del codice PyMySQL. Lì, request[1] è l'input.

14

Sebbene la risposta "risolta" funzioni, non è consigliabile. Quando si utilizza una libreria conforme al DBI Python, si dovrebbero usare le variabili di binding invece di formattare una stringa e passarla per l'esecuzione. Esistono pericoli inerenti a tale metodologia.

Pertanto, questo è il modo giusto per farlo:

cursor.execute("SELECT * FROM `Codes` WHERE `ShortCode` = %s", text) 

Si noti che questa non è una stringa di formato, ma una variabile si legano passato al cursore di esecuzione.

Per ulteriori dettagli: Python DBI PEP

+0

Nota che '% s' dovrebbe essere usato anche con tipi diversi, come i numeri interi. Stavo cercando di usare '% d' e ho ottenuto l'errore: 'Formato% d: è richiesto un numero, non str'. – nephets

0

Pronto per l'uso funzione di supporto

def mysql_insert(conn, table, row): 
    cols = ', '.join('`{}`'.format(col) for col in row.keys()) 
    vals = ', '.join('%({})s'.format(col) for col in row.keys()) 
    sql = 'INSERT INTO `{0}` ({1}) VALUES ({2})'.format(table, cols, vals) 
    conn.cursor().execute(sql, row) 
    conn.commit() 

esempio di utilizzo

insert_into(conn, 'people', { 
    'firstname': 'John', 
    'lastname': 'Doe', 
    'age': 18, }) 

Riferimento: https://github.com/PyMySQL/PyMySQL/blob/master/pymysql/cursors.py#L157-L158

def execute(self, query, args=None):

If args is a list or tuple, %s can be used as a placeholder in the query. 
If args is a dict, %(name)s can be used as a placeholder in the query.