2010-06-28 15 views
19

Sto avendo difficoltà a trovare alcuni sql in python per passare correttamente a MySQLdb. È la formattazione delle corde dei pitoni che mi sta uccidendo.Formati di stringhe Python con caratteri jolly SQL e LIKE

La mia istruzione sql utilizza la parola chiave LIKE con caratteri jolly. Ho provato una serie di cose diverse in Python. Il problema è che una volta che riesco a far funzionare uno di loro, c'è una riga di codice in MySQLdb che rutta sul formato stringa.

Tentativo 1:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query)

Questo è un no go. Ottengo l'errore valore:

ValueError: unsupported format character ''' (0x27) at index 128

Tentativo 2:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '\%%s\%'" % (query)

ottengo lo stesso risultato dal tentativo 1.

Tentativo 3:

like = "LIKE '%" + str(query) + "%'" totalq = "SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username " + like

Questo crea correttamente la totalq variabile, ma ora quando vado a eseguire la query ottengo errori da MySQLdb:

File "build/bdist.macosx-10.6-universal/egg/MySQLdb/cursors.py", line 158, in execute query = query % db.literal(args) TypeError: not enough arguments for format string

Tentativo 4:

like = "LIKE '\%" + str(query) + "\%'" totalq = "SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username " + like

Questa è la stessa uscita come il tentativo 3.

Tutto questo sembra davvero strano. Come posso utilizzare i caratteri jolly nelle istruzioni sql con python?

+0

Per echo @bernie di seguito: Da psycopg docs: http://initd.org/psycopg/docs/usage.html#the-problem-with-the-query-parameters: "Mai, mai, MAI usare la concatenazione di stringhe Python (+) o interpolazione dei parametri delle stringhe (%) per passare variabili a una stringa di query SQL. "Oltre agli attacchi SQL injection, un secondo vantaggio è che il driver" può convertire automaticamente oggetti Python in e letterali SQL: usando questa funzione il tuo codice sarà più robusto e affidabile ". Questo contro" un ingenuo approccio alla composizione delle stringhe di query, ad es usando la concatenazione di stringhe. " –

risposta

10

Non si tratta di formattazione delle stringhe, ma il problema è come query devono essere eseguite in base alle esigenze db operazioni in Python (PEP 249)

provare qualcosa di simile:

sql = "SELECT column FROM table WHERE col1=%s AND col2=%s" 
params = (col1_value, col2_value) 
cursor.execute(sql, params) 

here are some examples for psycog2 dove avete alcune spiegazioni che dovrebbe essere valido anche per mysql (mysqldb segue anche PEP249 dba api guidance 2.0: here are examples for mysqldb)

+0

Grazie. MySQL db capirebbe come scappare i parametri anche all'interno dell'istruzione sql, ma ora ha senso inserire parametri in questo modo: – gngrwzrd

+0

Sono contento che ti abbia aiutato! Ho passato molto tempo finché non l'ho capito qualche tempo fa :) – dzida

6

Per uscire ampersands in Python espressioni formattazione di stringhe, raddoppiare la e commerciale:

'%%%s%%' % search_string 

Edit: Ma Sono assolutamente d'accordo con un'altra risposta. La sostituzione diretta delle stringhe nelle query SQL è quasi sempre una cattiva idea.

20

Queste query sembrano essere vulnerabili agli attacchi di SQL injection.

provare qualcosa di simile, invece:

curs.execute("""SELECT tag.userId, count(user.id) as totalRows 
        FROM user 
      INNER JOIN tag ON user.id = tag.userId 
       WHERE user.username LIKE %s""", ('%' + query + '%',)) 

Dove ci sono due argomenti di essere passato a execute().

+1

Anche questo sembra vulnerabile all'iniezione di SQL.Utilizzare query parametrizzate attraverso qualunque libreria viene utilizzata per connettersi al database è la strada da percorrere – jrdioko

+4

@jrdioko: grazie per il tuo commento.Nota che non c'è un'interpolazione di stringa effettiva e che la query * è * preparata con il metodo 'execute()' – bernie

+0

Riporto indietro, sembra che la sintassi sia come la libreria in questione esegue le query con parametri – jrdioko

-1

ho una soluzione al vostro problema:

Non è possibile utilizzare:

"SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN tag ON user.id = tag.userId WHERE user.username LIKE '%%s%'" % (query) 

si può cambiare con il modello di stringa, come ad esempio:

import MySQLdb 
import string # string module 
....... 
value = {'user':'your value'} 
sql_template = string.Template(""" 
SELECT tag.userId, count(user.id) as totalRows FROM user INNER JOIN 
tag ON user.id = tag.userId WHERE user.username LIKE '%$user%' 
""") 

sql = sql_template.substitute(value) 

try: 
    cursor.execute(sql) 
    ........... 
except: 
    ........... 
finally : 
    db.close() 
+0

Questo non è migliore della sostituzione diretta che non dovresti fare comunque. Segnaposto come descritto sopra e nel documento PEP 249 descrivere come farlo correttamente – Turk