Manipuler une base de données SQLite avec Python
On ne peut pas appeler directement une requête SQL à partir de l'interpréteur.
Toute requête SQL doit être intégrée dans une commande Python.
Manipuler une base de données sqlite3 à partir de l'interpréteur
Avant d'attaquer la programmation de bases de données, il faut mieux tester des commandes dans l'interpréteur.
Commandes à saisir dans l'interpréteur Python
>>> import os
>>> os.chdir("c:/python_prog")
>>> import sqlite3
>>> connexion = sqlite3.connect("animaux.db")
>>> curseur = connexion.cursor()
>>> type(curseur)
>>>
>>> curseur.execute("SELECT * from taxons;")
>>> for resultat in curseur:
... print(resultat)
...
('hydr', 'hydraires')
('medu', 'méduses')
('acti', 'actinies')
...
('pinn', 'pinnipèdes')
('sire', 'siréniens')
('epon', 'éponges')
>>>
Il faut changer de répertoire courant donc importer le module "os".
Il faut 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.
Ensuite il faut créer un objet de type cursor(). Ici cet objet est nommé "curseur".
C'est cet objet qui récupère le résultat d'une requête sous forme de tuples.
On peut appliquer à cet objet "cursor" la méthode execute() qui permet d'appeler n'importe quel type de requête.
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.
Notez que 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()"
On peut appliquer à un objet de type "cursor" d'autres méthodes :
- fetchone()
- fetchall()
C'est ce que nous voyons ci-dessous.
>>> curseur.execute("SELECT * FROM vue4")
>>>
>>> ligne1 = curseur.fetchone()
>>> print(ligne1)
(1, 'homard', 'deca', 'deca', 'décapodes')
>>>
La méthode fetchone(), appliquée à l'objet de type cursor(), permet de récupérer l'enregistrement courant.
>>> lignes = curseur.fetchall()
>>> for ligne in lignes:
... print(ligne[1], ligne[3], ligne[4])
...
homard deca décapodes
orange de mer epon éponges
...
étrille deca décapodes
tourteau deca décapodes
...
>>>
La méthode fetchall() appliquée au curseur permet de récupérer toutes les lignes correspondant à la requête.
Pour se débarrasser des parenthèses, crochets, guillemets il suffit de pratiquer le "slicing" (ou tranchage).
Par exemple écrire print(ligne[1], ligne[3], ligne[4]) au lieu de print()
>>> curseur.execute("select * from vue4 where id = 4")
>>> curseur.fetchone()
(4, 'crevette grise', 'deca', 'deca', 'décapodes')
>>>
La requête sélectionne l'enregistrement dont l'id vaut 4.
curseur.fetchone() : affiche cette ligne sous la forme d'un tuple.
>>> identifiant = 20
>>> curseur.execute("select * from vue4 where id =?",(identifiant,))
>>> curseur.fetchone()
(20, 'roussette', 'cart', 'cart', 'cartilagineux')
>>>
Commandes très importantes : critère de filtrage de la requête = variable.
Nous saisissons 20 dans une variable et nous voulons qu'ensuite
ce soit la ligne dont l'id vaut 20 qui s'affiche. Donc nous voulons que le critère de filtrage soit le contenu d'une variable.
Comme vous voyez la syntaxe est particulière.
>>> curseur.execute("select max(id) from vue4")
>>> tuple = curseur.fetchone()
>>> tuple[0]
24
Une requête sélection de type SELECT MAX … retourne une seule ligne.
tuple = curseur.fetchone() : la méthode fetchone() retourne un tuple dont le contenu est (24,)
Avec le "slicing" on récupère uniquement le nombre 24.
>>> curseur.execute("select code, count(*) from especes2 group by code")
>>> contenu = curseur.fetchall()
>>> for ligne in contenu:
... print(ligne[0], ligne[1])
...
biva 4
cart 2
deca 6
epon 2
gast 2
osse 8
contenu = curseur.fetchall() : retourne 6 tuples car il y a 6 valeurs distinctes dans la colonne "especes2.code"
Toujours avec le "slicing", on se débarrasse des parenthèses et des guillemets.
N'oubliez pas de ferme la connexion.
Il faut appliquer la méthode close() à l'objet de type "connect".
>>>connexion.close()
Un programme de jeu qui exploite une base de données
Maintenant vous êtes prêt à aborder la programmation d'une base de données.
Thématique
Nous allons programmer un jeu.
Le joueur doit classer des espèces d'animaux marins. Dix espèces sont tirées au sort.
Pour chaque espèce le joueur doit préciser le taxon correspondant : saisie du code du taxon.
Le score maximal est 10.
Le code du programme
#nom programme : classer_especes.py
import sqlite3
import random
connexion = sqlite3.connect("animaux.db")
curseur = connexion.cursor()
curseur.execute("select * from taxons order by nom_taxon")
print("Liste des taxons avec entre () leur code")
lignes = curseur.fetchall()
for ligne in lignes:
print(ligne[1], "(" ,ligne[0] , ")",end = " - ")
print("----------------------------")
curseur.execute("select max(id) from vue4")
ligne =curseur.fetchone()
n = ligne[0] # n = valeur maxi du champ id
score = 0
for i in range(1,11):
alea = random.randint(1,n) # génération d'un entier inférieur au nombre de lignes
curseur.execute("select * from vue4 where id =?",(alea,) )
ligne = curseur.fetchone()
print("--------------------------")
print(ligne[1], end= " : ")
reponse = input(" appartient au taxon codé ? : ")
reponse = reponse.lower()
if ligne[3] in reponse: #si code_taxon est contenu dans reponse
score =score +1
else:
print("faux")
print("votre score sur 10 : " , score)
connexion.close()
Le code de la vue "vue4" qui est appelée dans ce programme
CREATE VIEW "vue4" AS select * FROM especes, taxons WHERE especes.code = taxons.code
Notez donc le rang des champs : id, nom_espece, especes.code, taxons.code, nom_taxon
Donc pour "slicer" le champ "nom_espece" l'indice doit être égal à 1
Le rendu
Liste des taxons avec entre () leur code
actinies ( acti ) - agnathes ( agna ) - amphipodes ( amph ) - annélidés ( anne ) -
ascidies ( asci ) - astérides ( aste ) -
bivalves ( biva ) - chitons ( chit ) - cirripèdes ( cirr ) - crinoïdes ( crin ) -
cténaires ( cten ) - céphalopodes ( ceph ) -
cétacés ( ceta ) - décapodes ( deca ) - echinidés ( echi ) - gastéropodes ( gast ) -
holoturies ( holo ) - hydraires ( hydr ) -
méduses ( medu ) - ophiures ( ophi ) - pinnipèdes ( pinn ) - poissons cartilagineux ( cart ) -
poissons osseux ( osse ) -
siréniens ( sire ) - vers plats ( plat ) - éponges ( epon ) -
--------------------------
araignée de mer : appartient au taxon codé ? : decap
--------------------------
talitre : appartient au taxon codé ? : amphi
--------------------------
morue : appartient au taxon codé ? : Osse
--------------------------
roussette : appartient au taxon codé ? : carti
--------------------------
coque : appartient au taxon codé ? : bival
--------------------------
sole : appartient au taxon codé ? : osse
--------------------------
langoustine : appartient au taxon codé ? : decap
--------------------------
balane : appartient au taxon codé ? : cirri
--------------------------
morue : appartient au taxon codé ? : OSSE
--------------------------
hareng : appartient au taxon codé ? : osse
Votre score sur 10 : 10
Commentaire
Le programme a besoin des modules random & sqlite3
Le programme affiche d'abord un "pense-bête" : la liste des taxons avec pour chaque son code donc faire appel à la table "taxons" ordonnée sur "nom_taxon".
Il faut récupérer la valeur maximale du champ "id" dans la "vue4".
Cette valeur est stockée dans la variable "n".
Une boucle est exécutée 10 fois (de 1 à 11 exclu). Dans cette boucle :
- génération aléatoire d'un entier compris entre 1 et n ; cet entier est stocké dans "alea"
- la variable "alea" sert de critère pour sélectionner un enregistrement de la vue "vue4"
- affichage uniquement du champ "nom_espece"
- le joueur doit alors saisir le code du taxon correspondant. Il doit en principe saisir 4 lettres minuscules non accentuées.
Mais grâce aux instructions reponse = reponse.lower() et if ligne[3] in reponse: il y a une grande tolérence.
Le joueur peut saisir en majuscules et saisir plus de 4 lettres (comme le montre le rendu) à condition que les 4 premières correspondent au contenu
du champ "code".
- les points acquis sont stockés dans la variable "score"
- ne pas oublier de fermer la base de données proprement