MySQL query con parametri
-
13-09-2019 - |
Domanda
Sto avendo un momento difficile utilizzando il MySQLdb modulo per inserire le informazioni nel mio database.Ho bisogno di inserire 6 variabili in tabella.
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(var1, var2, var3, var4, var5, var6)
""")
Qualcuno mi può aiutare con la sintassi qui?
Soluzione
Attenzione di utilizzare stringhe di interpolazione per le query SQL, dal momento che non sfuggirà i parametri di input corretto e lascerà la vostra applicazione aperta a vulnerabilità SQL injection. La differenza potrebbe sembrare banale, ma in realtà è enorme .
non corretto (con problemi di sicurezza)
c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s" % (param1, param2))
Corretto (fuoriuscita)
c.execute("SELECT * FROM foo WHERE bar = %s AND baz = %s", (param1, param2))
Si aggiunge alla confusione che i modificatori utilizzati per legare i parametri in un'istruzione SQL varia tra le diverse implementazioni DB API e che la libreria client MySQL utilizza printf
sintassi di stile al posto del più comunemente accettata '?' marcatore (usato da esempio. python-sqlite
).
Altri suggerimenti
Hai alcune opzioni disponibili. Avrai voglia di mettersi a proprio agio con iterpolation stringa di pitone. Che è un termine che si potrebbe avere più successo cercare in futuro, quando si vuole sapere cose come questa.
Una migliore per le query:
some_dictionary_with_the_data = {
'name': 'awesome song',
'artist': 'some band',
etc...
}
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(%(name)s, %(artist)s, %(album)s, %(genre)s, %(length)s, %(location)s)
""", some_dictionary_with_the_data)
Considerando probabilmente avete tutti i dati in un oggetto o già dizionario, il secondo formato si adatta meglio. Inoltre fa schifo dover contare "% s" apparizioni in una stringa quando si deve tornare indietro e aggiornare questo metodo in un anno:)
La documentazione legati danno il seguente esempio:
cursor.execute ("""
UPDATE animal SET name = %s
WHERE name = %s
""", ("snake", "turtle"))
print "Number of rows updated: %d" % cursor.rowcount
Quindi, non vi resta che adattare questo per il proprio codice - ad esempio:
cursor.execute ("""
INSERT INTO Songs (SongName, SongArtist, SongAlbum, SongGenre, SongLength, SongLocation)
VALUES
(%s, %s, %s, %s, %s, %s)
""", (var1, var2, var3, var4, var5, var6))
(Se SongLength è numerico, potrebbe essere necessario utilizzare% d al posto di% s).
In realtà, anche se la variabile (SongLength) è numerico, sarà comunque necessario formattarla con% s al fine di impegnare correttamente il parametro. Se si tenta di utilizzare% d, si otterrà un errore. Ecco un piccolo estratto da questo link http://mysql-python.sourceforge.net/MySQLdb.html :
Per eseguire una query, è necessario prima un cursore, e quindi è possibile eseguire query su di esso:
c=db.cursor()
max_price=5
c.execute("""SELECT spam, eggs, sausage FROM breakfast
WHERE price < %s""", (max_price,))
In questo esempio, MAX_PRICE = 5 Perché, allora, utilizzare% s nella stringa? Perché MySQLdb verrà convertito in un valore letterale SQL, che è la stringa '5'. Quando è finito, la query sarà effettivamente dire:" ... DOVE prezzo <5" .
Come alternativa alla risposta scelta, e con la stessa sicurezza di una semantica di Marcel, qui è un modo compatto di utilizzo di un dizionario Python per specificare i valori.Ha il vantaggio di essere facile da modificare come aggiungere o rimuovere colonne per inserire:
meta_cols=('SongName','SongArtist','SongAlbum','SongGenre')
insert='insert into Songs ({0}) values ({1})'.
.format(','.join(meta_cols), ','.join( ['%s']*len(meta_cols) ))
args = [ meta[i] for i in meta_cols ]
cursor=db.cursor()
cursor.execute(insert,args)
db.commit()
Dove meta è il dizionario contenente i valori da inserire.L'aggiornamento può essere fatto nello stesso modo:
meta_cols=('SongName','SongArtist','SongAlbum','SongGenre')
update='update Songs set {0} where id=%s'.
.format(','.join([ '{0}=%s'.format(c) for c in meta_cols ]))
args = [ meta[i] for i in meta_cols ]
args.append( songid )
cursor=db.cursor()
cursor.execute(update,args)
db.commit()
Ecco un altro modo per farlo. E 'documentato sul sito ufficiale di MySQL. https: //dev.mysql. com / doc / connettore-python / it / connettore-python-api-mysqlcursor-execute.html
Nello spirito, che sta utilizzando la stessa meccanica della risposta di @Trey Stout. Tuttavia, ho trovato questo più bella e più leggibile.
insert_stmt = (
"INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
"VALUES (%s, %s, %s, %s)"
)
data = (2, 'Jane', 'Doe', datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)
E per illustrare meglio qualsiasi esigenza per le variabili:
NB:. Si noti la fuga viene fatto
employee_id = 2
first_name = "Jane"
last_name = "Doe"
insert_stmt = (
"INSERT INTO employees (emp_no, first_name, last_name, hire_date) "
"VALUES (%s, %s, %s, %s)"
)
data = (employee_id, conn.escape_string(first_name), conn.escape_string(last_name), datetime.date(2012, 3, 23))
cursor.execute(insert_stmt, data)
La prima soluzione funziona bene. Voglio aggiungere un piccolo dettaglio qui. Assicurarsi che la variabile che si sta cercando di sostituire / aggiornare lo farà deve essere un tipo str. Il mio tipo mysql è decimale, ma ho dovuto fare la variabile parametro come str essere in grado di eseguire la query.
temp = "100"
myCursor.execute("UPDATE testDB.UPS SET netAmount = %s WHERE auditSysNum = '42452'",(temp,))
myCursor.execute(var)