2008-11-24 4 views
6

Weiß jemand, ob es eine Möglichkeit gibt, eine Liste in Python automatisch zu erweitern, getrennt durch Kommas? Ich schreibe Python-Code, der die MySQLdb-Bibliothek verwendet, und ich versuche, eine Liste von Zeilen in einer MySQL-Datenbank mit bestimmten Schlüsselwerten dynamisch zu aktualisieren.Automatische Erweiterung einer Python-Liste mit formatierter Ausgabe

Zum Beispiel möchte ich die numerischen Werte in der Liste record_ids im folgenden Code in eine SQL "IN" -Klausel erweitern.

import MySQLdb 
record_ids = [ 23, 43, 71, 102, 121, 241 ] 

mysql = MySQLdb.connect(user="username", passwd="secret", db="apps") 
mysql_cursor = mysql.cursor() 

sqlStmt="UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 

mysql_cursor.execute(sqlStmt, record_ids) 
mysql.commit() 

Jede Hilfe wäre willkommen!

Antwort

18

Versuch:

",".join(map(str, record_ids)) 

",".join(list_of_strings) eine Liste der Zeichenfolge schließt sich, indem sie mit Kommas trennen

, wenn Sie eine Liste von Zahlen haben, werden map(str, list) es von Strings

+0

Danke, tat dies der Trick! – m0j0

2

Weitere in eine Liste konvertieren zu den gegebenen Antworten, beachten Sie, dass Sie möglicherweise möchten, Sonderfall der leere Listenfall als "where rec_id in()" ist nicht gültig SQL, so erhalten Sie einen Fehler.

Seien Sie auch sehr vorsichtig beim manuellen Erstellen von SQL, anstatt nur automatisch maskierte Parameter zu verwenden. Für eine Liste von ganzen Zahlen wird es funktionieren, aber wenn Sie mit Strings arbeiten, die von Benutzereingaben empfangen werden, öffnen Sie damit eine große SQL-Injection-Schwachstelle.

+0

+1 Bitte verwenden Sie Bind-Variablen. http://stackoverflow.com/questions/1973/what-ist-the-best-way-to-avoid-sql-injectionattacks –

+0

Dies wird nur Daten aus einer Datenbank lesen und Daten aktualisieren. Es wird niemals Daten aus dem Internet verwenden. – m0j0

+0

Vorsicht: Viele Daten in Datenbanken werden letztendlich von Benutzern eingegeben. Selbst wenn Ihr Fall vollkommen sicher ist, können einige spätere Kordern mit einem ähnlichen Problem beschließen, vorhandenen Code zu kopieren. Es ist eine gute Idee, sich um diese Dinge zu kümmern, auch wenn es sicher ist. Es ist besser, gute Gewohnheiten zu stärken und vorzuzeigen als schlecht. – Brian

1

ich tun, wie diese Sachen (um sicherzustellen, ich bin mit Bindungen):

sqlStmt=("UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 
    % ', '.join(['?' for n in record_ids])) 

mysql_cursor.execute(sqlStmt, record_ids) 
mysql.commit() 

Dies funktioniert für alle dynamischen Listen, die Sie ohne binden möchten verlassen Sie SQL-Injection-Angriffe anfällig.

+0

Ich glaube nicht, dass Fragezeichen für MySQL-Bindungen funktionieren. – m0j0

+0

Das ist der Nachteil von Pythons DB API. Ich habe das oben für sqlite und postgres gemacht, aber es liegt am Fahrer zu entscheiden, wie Bindungen funktionieren. Derselbe Grundsatz gilt jedoch. Bindungen generieren und Daten einspeisen – Dustin

0

Etwas andere Alternative zu Dustin Antwort:

sqlStmt=("UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in (%s)" 
    % ', '.join(['?' * len(record_ids]))) 
+0

Das erweitert sich nicht richtig, aber das tut: ',' .join ('?' * Len (record_ids)) - Ich mag das irgendwie, obwohl es sich leicht falsch anfühlt. – Dustin

0

Alternitavely, mit ersetzen:

sqlStmt="UPDATE apps.sometable SET lastmod=SYSDATE() where rec_id in " + 
    record_ids.__str__().replace('[','(').replace(']',')')