Les opérations qui changent le contenu de la base de données par programmation sont plus complexes que celles qui ne font qu'une simple lecture avec un SELECT.
Dans un programme qui doit ajouter, modifier ou supprimer des données, l'organisation du code sera passablement différente.
Il est très rare que les informations à enregistrer soient toutes connues d'avance. C'est pourquoi on permettra à l'usager de fournir les informations désirées puis on se chargera de les enregistrer dans la base de données.
Voici un exemple dans un programme console :
description = input('Veuillez entrer la description de l\'item à ajouter : ')
quantite = input('Veuillez entrer la quantité :')
...
requete = 'INSERT INTO items(description, quantite) VALUES(?, ?)'
curseur.execute(requete, (description, quantite))
...
Il est important de savoir que dans une BD SQLite, les opérations d'ajout, de modification et de suppression de données dans un programme Python se déroulent dans un premier temps en mémoire vive.
Rien ne sera enregistré dans la base de données tant que l'on n'exécutera pas la fonction commit().
Ceci est très pratique puisque ça permet de défaire une série de modifications au besoin. Mais si on oublie le commit() alors qu'on désirait conserver les modifications, tout sera perdu.
Ex :
requete = 'INSERT INTO categories(description) VALUES(?)'
curseur.execute(requete, (description.get(),))
connexion.commit()
De nombreux facteurs peuvent empêcher une insertion de fonctionner.
Un INSERT pourrait échouer, par exemple, parce qu'on tente d'insérer dans un champ unique une valeur qui existe déjà.
Ex :
requete = 'INSERT INTO usagers(code, nomfamille, prenom) VALUES(?, ?, ?)'
curseur.execute(requete, ('toto', 'Lacasse', 'Toto'))
# cette requête va échouer si le champ code doit être unique
Dans le cas d'une clé étrangère, la requête INSERT échouera si on lui fournit une valeur qui n'existe pas dans la table liée.
Ex :
requete = 'INSERT INTO produits(code, description, categorie_id) VALUES(?, ?, ?)'
curseur.execute(requete, ('abc', 'Produit ABC', 36)) # cette requête va échouer s'il n'existe pas de catégorie dont le id est 36
La meilleure technique pour réagir en cas de problème, c'est le try...except.
Ex :
try:
requete = 'INSERT INTO usagers(code, nomfamille, prenom) VALUES(?, ?, ?)'
curseur.execute(requete, (code.get(), nom_famille.get(), prenom.get()))
connexion.commit()
except sqlite3.OperationalError as e:
print('Un problème a empêché l\'ajout de l\'usager.')
traceback.print_exc(file=sys.stdout)
except Exception as e:
print('Une erreur inattendue est survenue.')
traceback.print_exc(file=sys.stdout)
Il pourra y avoir plusieurs blocs try...except dans un même programme Python. Ceci permettra d'avoir un message personnalisé en fonction de l'opération exécutée.
Ex :
# Branchement à la base de données
try:
connexion = None
connexion = sqlite3.connect('file:mabd.db?mode=rw', uri=True)
...
except sqlite3.OperationalError as e:
print('La connexion à la base de données a échoué.')
traceback.print_exc(file=sys.stdout)
...
# Lecture des données
try:
requete = 'SELECT ...'
...
except sqlite3.OperationalError as e:
print('Il y a une erreur dans la requête SQL.')
traceback.print_exc(file=sys.stdout)
...
# Insertion de données
try:
requete = 'INSERT ...'
...
except sqlite3.OperationalError as e:
print('Un problème a empêché l\'ajout de l\'usager.')
traceback.print_exc(file=sys.stdout)
...
▼Publicité