Accueil

Traduction

Tutoriel Python - sommaire

Tutoriel Python - recherche

L'auteur : Patrick Darcheville

Vous pouvez me contacter via Facebook pour questions & suggestions : Page Facebook relative à mon site

Manipuler une base de données SQLite avec Python

Dans le chapitre précédent nous avons manipulé une base de donnée SQLite à partir du logiciel DB browser(for SQLite).
Mais on peut manipuler cette base via l'interpréteur Python ou dans le cadre d'un programme Python.
Je vous rappelle que la base "animaux.db" comprend deux tables : 'especes' & 'taxons' avec un champ de jointure entre ces deux tables, champ qui porte le même nom dans les deux tables : 'code'.

Lire les tables de la base

Nous alons tout d'abord utiliser la console Python.

Lire la table "taxons"

Attention, la base de données "animaux.db" est stockée dans le dossier "c:\python_prog". Or le répertoire par défaut pour l'interpréteur est "c:\python39". Il faut donc changer de répertoire courant et donc importer le module "os" pour disposer de la fonction chdir().
Pour manipuler une base de données SQLite, il faut donc importer le module "sqlite3".
Il faut ensuite se connecter à une base de données avec la méthode connect() du module sqlite3 et donc créer un objet de type connection.

Ensuite il faut créer un objet de type cursor(). Ici cet objet est nommé "curseur".
On peut appliquer à cet objet "cursor" la méthode execute() qui permet d'appeler n'importe quel type de requête SQL.

Éxaminons quelques commandes :
curseur.execute("SELECT * from taxons;") : pour récupérer dans l'objet "cursor" tout le contenu de "taxons".
for resultat in curseur : l'objet de type "cursor" est itérable.
Les contenus sont retournés sous forme de tuples. Ce n'est donc pas très lisible à cause des parenthèses, des guillemets simples qui parasitent l'affichage.

Autres méthodes applicables à l'objet "cursor()"

La méthode fetchone()

La méthode fetchone(), appliquée à l'objet de type cursor(), permet de récupérer l'enregistrement courant sous forme d'un tuple.

Rappel de la syntaxe de "vue1" : CREATE VIEW "vue1" AS SELECT nom_espece, taxons.code, nom_taxon FROM especes INNER JOIN taxons ON especes.code = taxons.code

La méthode fetchall()

Cette méthodé appliquée au curseur permet de récupérer toutes les lignes correspondant à la requête sous forme de tuples.
Pour se débarrasser des parenthèses, crochets, guillemets il suffit de pratiquer le "slicing" (ou tranchage). Voir l'exemple qui suit.

La méthode fetchmany(n)

Cette méthode permet de récupérer un nombre de lignes correspondant à la valeur passée en paramètre.
En supposant que vous êtes connecté à la base "animaux.db", Les commandes qui suivent sont :

On affiche bien 10 lignes.

Requête sélection avec filtrage

Le critère de filtrage est une constante

La requête sélectionne l'enregistrement dont l'id vaut 4.
curseur.fetchone() : affiche cette ligne sous la forme d'un tuple.

Le critère de filtrage est une variable

Nous affectons 20 dans la variable "identifiant" et nous voulons qu'ensuite ce soit l'enregistrement dont l'id correspond au contenu de cette variable qui s'affiche.
Comme vous voyez ci-dessus la syntaxe est particulière : select ... id =?", (nomVariable,)
N'oubliez pas la virgule avant de fermer la parenthèse pour préciser que le tuple ne contient qu'une valeur sinon plantage !

Requête sélection statistique avec regroupements

contenu = curseur.fetchall() : retourne 14 tuples car il y a 14 valeurs distinctes dans la colonne "especes.code"
Avec le "slicing", on se débarrasse des parenthèses et des guillemets.

Se déconnecter de la base de données

N'oubliez pas de fermer la connexion avec la base.
Il faut appliquer la méthode close() à l'objet de type "connect" et si cet objet se nomme "connexion", la commande est alors : connexion.close()

Programme pour parcourir une vue

Nous allons maintenant passer au mode programmé avec l'IDLE comme environnement de travail.
Je vous propose tout d'abord un programme qui parcoure la vue "vue1".

Rappel de "vue1"

CREATE VIEW "vue1" AS SELECT nom_espece, taxons.code, nom_taxon FROM especes INNER JOIN taxons ON especes.code = taxons.code
Cette vue mémorise une requête sélection multitables : associer à chaque ligne de "especes" une ligne de "taxons".

Le programme

Le programme et la BD étant stockés dans le même répertoire (c:\python_prog), l'instruction "chdir ... " est ici inutile.
Notez qu'en SQL on manipule une vue comme une table.

Le rendu

Extrait de la trace :
talitre amph amphipodes
ver bobbit anne annélidés
fraise de mer asci ascidies
cione asci ascidies
soleil de mer aste astérides
moule commune biva bivalves
...

Programme pour parcourir une table

Je vous propose maintenant un programme qui lit la table "especes".
Pour afficher les champs nous allons utiliser leur nom plutôt que leur indice.
Le code :

Notez l'instruction connexion.row_factory =sqlite3.Row qui va nous permettre d'utiliser les noms de champs à la place de leur indice : print(ligne['id'], ligne['nom_espece'], ligne['code'])

Le rendu

Extrait de la trace :

1 homard deca
4 crevette grise deca
5 bouquet deca
6 étrille deca
7 tourteau deca
8 araignée de mer deca
9 bulot gast
10 patelle gast
...

Programme de recherche dans une table

Les programmes ci-dessous permettent d'effectuer des recherches dans la table "especes" sur la colonne "nom_espece".
Ils sont basés sur des requêtes paramétrées.

Mauvaise solution

Le programme ci-dessous exige de la part de son utilisateur une grande rigueur de saisie. Ainsi s'il recherche la fiche sur le "Crabe vert" il doit saisir "Crabe vert" (avec un C majuscule) car le contenu de "nom_espece" pour cette ligne est "Crabe vert".

Le code

Dans (choix,) n'oubliez pas la "," avant de fermer la parenthèse pour préciser que le tuple ne contient qu'une valeur sinon plantage !

Le rendu

Tapez une partie du nom de l'espèce recherchée ou 'fin' : crabe vert
Tapez une partie du nom de l'espèce recherchée ou 'fin' : Crabe
Tapez une partie du nom de l'espèce recherchée ou 'fin' : Crabe vert
Crabe vert deca
Tapez une partie du nom de l'espèce recherchée ou 'fin' : 

J'ai du m'y prendre à trois fois pour enfin obtenir les infos sur l'espèce "crabe vert".

Solution correcte

Une requête paramétrée basée sur l'opérateur LIKE (plutôt que sur ==) offre à l'inverse une grande souplesse. En effet non seulement il n'est pas nécessaire de saisir le nom complet (mais simplement les premières lettres mais en plus l'opérateur LIKE est insensible à la casse.

Le code du programme "recherche_espece_ok.py"

La seule différence entre les deux programmes est la requête paramétrée.
Dans (choix+'%',) n'oubliez la virgule avant de fermer la parenthèse.

Le rendu

Tapez une partie du nom de l'espèce recherchée ou 'fin' : crab
crabe chinois deca
Crabe vert deca
Crabe japonais deca
Crabe marbré deca
Tapez une partie du nom de l'espèce recherchée ou 'fin' : 

Je saisis "crab" et j'obtiens toutes les lignes dont le contenu du champ "nom_espece" commence par "crab" que la lettre C soit en minuscule ou majuscule.

Insertion de lignes dans une table "especes"

Supprimons au préalable les poissons osseux de la table "especes" via la console Python :

...
>>> curseur.execute("delete from especes where code ='osse' ")

>>> connexion.commit()

En dehors de DB Browser toute requête (requête INSERT ou DELETE) qui modifie les données de la base doit être confirmée par la commit() de l'objet référant la connexion.

Programme qui ajoute des lignes à partir de données fournies par le script

Le code

Ici je vous montre comment intégrer des requêtes SQL INSERT dans un programme Python.
La variable un_poisson contient un tuple décrivant une seule espèce. La syntaxe pour insérer une seule ligne est : curseur.execute(requête insert, nomTuple)
la variable autres_poissons est une liste de 5 tuples. La syntaxe pour insérer 5 nouvelles lignes est : curseur.executemany(requête insert, nomListedeTuples).
Il faut valider la modification de la table avec la commande commit() puis il faut se déconnecter de la base.

Contrôle

Pour vérifier que 6 lignes (1 + 5) ont bien été ajoutées à la table "especes" il suffit de relancer le programme "lire_vue1.py" :

Trace d'exécution du programme :

...
murène osse poissons osseux
hareng osse poissons osseux
maquereau osse poissons osseux
morue osse poissons osseux
sardine osse poissons osseux
baudroie osse poissons osseux
...

Donc six enregistrements ont bien été ajoutés.

Programma qui insère des lignes à partir de données communiquées par l'utilisateur

C'est quand même plus pratique lorsque c'est l'utilisateur qui saisit les données.

Le code du programme

La méthode execute() comprend deux paramètres : code SQL, tuple de valeurs.

Le rendu

Trace d'exécution du programme :

SAISIR DE NOUVELLES ESPECES
nom de l'espèce : truite 
code du taxon corrrespondant : osse
nom de l'espèce : saumon
code du taxon corrrespondant : osse
nom de l'espèce : fin

Critique constructive de ce programme

Ce programme fonctionne mais n'est pas très ergonomique ... L'utilisateur doit connaitre par coeur les codes des différents taxons.

Sachez que tout cela est possible à condition d'utiliser le module tkinter.
Vous trouverez dans le chapitre suivant un programme de saisie dans la table "especes" dans le cadre d'un formulaire.

Récupération de la base "animaux.db"

La base de données SQLite 'animaux.db'