62 votes

Utilisation d'un dictateur Python pour une instruction SQL INSERT

J'essaie d'utiliser un dict pour faire un SQL INSERT . La logique serait essentiellement la suivante :

INSERT INTO table (dict.keys()) VALUES dict.values()

Cependant, j'ai du mal à trouver la syntaxe/le flux correct pour le faire. Voici ce que j'ai actuellement :

# data = {...}
sorted_column_headers_list = []
sorted_column_values_list = []
for k, v in data.items():
    sorted_column_headers_list.append(k)
    sorted_column_values_list.append(v)
sorted_column_headers_string = ', '.join(sorted_column_headers_list)
sorted_column_values_string = ', '.join(sorted_column_values_list)

cursor.execute("""INSERT INTO title (%s) 
            VALUES (%s)""", 
            (sorted_column_headers_string, sorted_column_values_string))

J'obtiens alors une exception SQL (je pense qu'elle est liée au fait que des virgules sont également incluses dans certaines de mes valeurs). Quelle serait la manière correcte de procéder ?

2voto

Albion Points 97

Ce code a fonctionné pour moi (Python 3) :

fields = (str(list(dictionary.keys()))[1:-1])
values = (str(list(dictionary.values()))[1:-1])
sql = 'INSERT INTO Table (' + fields + ') VALUES (' + values + ')'
cursor.execute(sql)

Elle repose sur le fait que le dictionnaire affiche ses clés et ses valeurs dans le même ordre. Je ne sais pas si cela est toujours vrai :)

2voto

snakecharmerb Points 8425

Lorsque l'on construit des requêtes de manière dynamique, il est important de s'assurer que les deux éléments suivants sont pris en considération identifiants y valeurs sont correctement cités. Sinon, vous risquez

  • Injection SQL si des données non fiables sont traitées
  • Erreurs si les noms de colonnes nécessitent des guillemets (par exemple, des espaces incorporés).
  • Corruption de données ou erreurs si les valeurs sont incorrectement citées (par exemple 2021-07-11 non cotées peuvent être évaluées comme 2003 )

La citation des valeurs est mieux déléguée au connecteur DB-API. Cependant, les packages des connecteurs ne fournissent pas toujours un moyen de citer les identifiants, vous devrez donc peut-être le faire manuellement. MySQL utilise des backticks (`) pour citer les identifiants.

Ce code cite des identifiants et des valeurs. I

data = {'col1': val1, 'col2': val2, ...}

# Compose a string of quoted column names
cols = ','.join([f'`{k}`' for k in data.keys()])

# Compose a string of placeholders for values
vals = ','.join(['%s'] * len(data))

# Create the SQL statement
stmt = f'INSERT INTO `tbl` ({cols}) VALUES ({vals})'

# Execute the statement, delegating the quoting of values to the connector
cur.execute(stmt, tuple(data.values()))

2voto

hsamba Points 29
table='mytable'    
columns_string= '('+','.join(myDict.keys())+')'    
values_string = '('+','.join(map(str,myDict.values()))+')'    
sql = """INSERT INTO %s %s
     VALUES %s"""%(table, columns_string,values_string)

0 votes

Bonne réponse. Mais pour être plus pratique, il faut supprimer un guillemet simple dans la jointure. '(\''+'\',\''.join(myDict.keys())+'\')' ou mieux "('"+"','".join(myDict.keys())+"')"

0voto

Uday S Points 496

J'ai utilisé ce fil pour mon usage et j'ai essayé de le garder beaucoup plus simple.

ins_qry = "INSERT INTO {tablename} ({columns}) VALUES {values};" .format(
            tablename=my_tablename,
            columns=', '.join(myDict.keys()),
            values=tuple(myDict.values())
        )
cursor.execute(ins_qry)

Veillez à valider les données insérées, soit en utilisant l'option db_connection.commit() et utiliser cursor.lastrowid si vous avez besoin de la clé primaire de la ligne insérée.

0voto

EmmaYang Points 165
columns = ', '.join(str(x).replace('/', '_')  for x in row_dict.keys())

values = ', '.join("'" + str(x).replace('/', '_') + "'" for x in row_dict.values())

sql = "INSERT INTO %s ( %s ) VALUES ( %s );" % ("tablename", columns, values)

applicable pour python3

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X