2008-11-24 15 views
6

¿Alguien sabe si hay una forma de expandir automáticamente una lista en Python, separada por comas? Estoy escribiendo un código Python que usa la biblioteca MySQLdb, y estoy tratando de actualizar dinámicamente una lista de filas en una base de datos MySQL con ciertos valores clave.Expandir automáticamente una lista de Python con salida formateada

Por ejemplo, en el siguiente código, me gustaría que los valores numéricos en la lista de record_ids se expandan en una cláusula "IN" de SQL.

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

¡Cualquier ayuda sería apreciada!

Respuesta

18

intento:

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

",".join(list_of_strings) se une a una lista de cadena separándolas por comas

si usted tiene una lista de números, map(str, list) lo convertirá en una lista de cadenas

+0

Gracias, esto hizo el truco! – m0j0

2

Más a las respuestas dadas, tenga en cuenta que es posible que desee un caso especial el caso de lista vacía como "where rec_id in()" no es SQL válido, por lo que obtendrá un error.

También tenga mucho cuidado de construir SQL manualmente de esta manera, en lugar de simplemente usar los parámetros escapados automáticamente. Para una lista de enteros, funcionará, pero si se trata de cadenas recibidas de la entrada del usuario, se abre una gran vulnerabilidad de inyección SQL al hacer esto.

+0

+1 Por favor, use variables de enlace. http://stackoverflow.com/questions/1973/what-is-the-best-way-to-avoid-sql-injection-attacks –

+0

Esto solo leerá datos de una base de datos y actualizará datos. Nunca usará los datos ingresados ​​de Internet. – m0j0

+0

Cuidado: muchos datos en las bases de datos son finalmente ingresados ​​por los usuarios. Incluso si su caso es perfectamente seguro, algunos corder posteriores con un problema similar pueden decidir copiar el código existente. Es una buena idea preocuparse por estas cosas incluso cuando es seguro. Es mejor reforzar y exhibir buenos hábitos que malos. – Brian

1

que hacer cosas como esta (para asegurarse de que estoy usando enlaces):

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

Esto funciona para todas las listas dinámicas que desea unirse sin dejar más susceptible a ataques de inyección SQL.

+0

No creo que los signos de interrogación funcionen para los enlaces MySQL. – m0j0

+0

Esa es la desventaja de la API DB de python. He hecho lo anterior para sqlite y postgres, pero depende del controlador decidir cómo funcionan las vinculaciones. El mismo principio se aplica, sin embargo. Genere enlaces y alimente los datos. – Dustin

0

alternativa un poco diferente a la respuesta de Dustin:

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

Eso no se expande correctamente, pero esto lo hace: ',' .join ('?' * Len (record_ids)) - Me gusta eso, aunque se siente un poco mal. – Dustin

0

Alternitavely, utilizando reemplazar:

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