Erreur : Incorrect number of bindings supplied

Bonjour,
je reste dans le sujet de KYROB :
Erreur Python Sqlite3: near “%”: syntax error

j’utilise le même type de code et j’ai aussi galéré avec la syntaxe de ce code (pour les variables).
Après recherches j’ai trouvé sur votre site (ma bible maintenant!) ce code :

qui permet de rentrer des variables paramétrées.

ce code fonctionne parfaitement, je l’ai mis en œuvre avec des variables plus complexes (avec \ pour les chemins des répertoires, fruits de ma galère dans la syntaxe…) pas de problème. ici la base a 1 index et 2 champs.

par contre si j’utilise une base de données qui n’a qu’un seul champ (plus index, bien sûr), j’ai l’erreur suivante. ici la base a 1 index et 1 champ
« Erreur lors de l’insertion dans la table person Incorrect number of bindings supplied. The current statement uses 1, and there are 3 supplied. »
Dans mon cas, le 3 correspond au nombre de caractères de la valeur à enregistrer. Si je veux enregistrer un texte de 12 car, j’ai « 12 supplied ».
ci dessous le code du site « modifié » pour une base avec 2 champs au lieu de 3 (y compris l’index).

-- coding: utf-8 --

import sqlite3

def insert_into(name):
	try:
		conn = sqlite3.connect('my_db_1_champ.db')
		cur = conn.cursor()
		print("Connexion réussie à SQLite")

		sql = "INSERT INTO person (name) VALUES (?)"

		value = (name)
		#cur.execute("INSERT INTO person (name, address) VALUES ('totot','test')")
		cur.execute(sql, value)
		conn.commit()
		print("Enregistrement inséré avec succès dans la table person")
		cur.close()
		conn.close()
		print("Connexion SQLite est fermée")

	except sqlite3.Error as error:
		print("Erreur lors de l'insertion dans la table person", error)


#ma_chaine= "test var\\tets"

#insert_into('c:\\test\\')
insert_into('Bob')

quelque chose m’échappe entre 2 champs et 1 champ.

j’ai contourné le problème en ajoutant un champ « vide », mais ça n’est pas très élégant…

Si vous avez de quoi éclairer ma lanterne, en espérant avoir décrit correctement mes soucis.

D’avance merci.
jym

utiliser (name,)

En bref :

cursor.execute s’attend à ce que le second paramètre soit un itérable.

Lorsque votre code demande

cursor.execute("INSERT INTO person (name) VALUES (?)", (name))

Alors (name) n’est pas un tuple - vous avez probablement voulu le convertir en un tuple en le mettant dans ().

Ce que vous voulez, c’est donc

cursor.execute("INSERT INTO person (name) VALUES (?)", (name,))

Remarquez le , ajouté !

Pour éviter cette confusion de tuple, vous pouvez aussi utiliser une liste :

cursor.execute("INSERT INTO person (name) VALUES (?)", [name])

Le problème de manière encore plus détaillée :

cursor.execute("INSERT INTO person (name) VALUES (?)", (name))

est le même que

cursor.execute("INSERT INTO person (name) VALUES (?)", name)

est identique (dans votre cas) à :

cursor.execute("INSERT INTO person (name) VALUES (?)", 'Bob')

La chaîne Bob est utilisée comme itérable, et comme elle comporte 3 caractères, vous obtenez l’erreur :

sqlite3.ProgrammingError: Incorrect number of bindings supplied. The current statement uses 1, and there are 3 supplied.

Vous obtenez cette erreur, car ici :

sql = "INSERT INTO person (name) VALUES (?)"
value = (name)
cur.execute(sql, value)

vous devriez passer, comme 2ème paramètre pour execute() un tuple et pas seulement une chaîne.
Ceci est facilement corrigé en ajoutant une virgule comme ceci :

sql = "INSERT INTO person (name) VALUES (?)"
value = (name,)
cur.execute(sql, value)

Merci Henri pour ces explications claires et la solution.
j’avoue venir de VB6 (pardon…) et ces notions de tuple et liste m’échappent un peu.
j’avais essayé de mettre cette virgule un peu partout, mais pas là!
C’est plus élégant que mon deuxième champ.
Encore merci, bonne journée.
jym