2008-11-24 7 views
6

Est-ce que quelqu'un sait s'il existe un moyen de développer automatiquement une liste en Python, en la séparant par des virgules? J'écris du code Python qui utilise la bibliothèque MySQLdb, et j'essaye de mettre à jour dynamiquement une liste de lignes dans une base de données MySQL avec certaines valeurs clés. Par exemple, dans le code ci-dessous, j'aimerais que les valeurs numériques de la liste record_ids se développent dans une clause SQL "IN".Développement automatique d'une liste Python avec une sortie formatée

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() 

Toute aide serait appréciée!

Répondre

18

essayer:

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

",".join(list_of_strings) se joint à une liste de chaînes en les séparant par des virgules

si vous avez une liste de numéros, map(str, list) se convertir en une liste de chaînes

+0

Merci, ce fait l'affaire! – m0j0

2

plus Pour les réponses données, notez que vous pouvez vouloir cas particulier le cas de liste vide comme "where rec_id in()" n'est pas valide SQL, donc vous obtiendrez une erreur.

Faites également très attention à la construction manuelle de SQL comme ceci, plutôt que d'utiliser simplement des paramètres échappés automatiquement. Pour une liste d'entiers, cela fonctionnera, mais si vous traitez des chaînes reçues de la part de l'utilisateur, vous ouvrez une énorme vulnérabilité d'injection SQL en faisant cela.

+0

+1 Veuillez utiliser les variables de liaison. http://stackoverflow.com/questions/1973/what-is-the-best-way-to-avoid-sql-injection-attacks –

+0

Cela ne fera que lire les données d'une base de données et mettre à jour les données. Il n'utilisera jamais les données saisies sur Internet. – m0j0

+0

Attention: de nombreuses données dans les bases de données sont finalement saisies par les utilisateurs. Même si votre cas est parfaitement sûr, certains corder plus tard avec un problème similaire peuvent décider de copier le code existant. C'est une bonne idée de se soucier de ces choses même quand c'est sûr. Mieux vaut renforcer et montrer de bonnes habitudes que mauvaises. – Brian

1

je fais des trucs comme ça (pour assurer que je utilise des liaisons):

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() 

Cela fonctionne pour toutes les listes dynamiques que vous voulez lier sans vous laisser sensible aux attaques par injection SQL.

+0

Je ne pense pas que les points d'interrogation fonctionnent pour les liaisons MySQL. – m0j0

+0

C'est l'inconvénient de l'API DB de python. J'ai fait ce qui précède pour sqlite et postgres, mais c'est au conducteur de décider comment fonctionnent les liaisons. Le même principe s'applique, cependant. Générez des liaisons et alimentez les données. – Dustin

0

alternative un peu différent de la réponse de Dustin:

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

Cela ne se développe pas correctement, mais ce n'est pas le cas: ',' .join ('?' * Len (record_ids)) - J'aime ça, même si ça fait un peu tort. – Dustin

0

Alternitavely, en utilisant remplacer:

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