Les bases de données
Pourquoi pas juste des fichiers CSV ?
Un fichier CSV marche bien pour 42 ventes. Mais imagine l'application MTN MoMo : des millions de clients, des milliers d'opérations chaque seconde, des agents partout qui consultent et modifient les soldes en même temps. Avec un fichier :
- pour trouver un client, il faudrait relire le fichier depuis le début ;
- si deux agents enregistrent une opération au même instant, l'une peut effacer l'autre ;
- si le courant coupe pendant l'écriture, le fichier peut être abîmé ;
- n'importe qui ayant accès au fichier peut tout lire.
Les tables
Dans une base de données relationnelle, le type le plus répandu, les données sont rangées dans des tables : des tableaux avec des colonnes nommées, exactement comme un DataFrame ou une feuille Excel.
| Mot | Sens |
|---|---|
| table | un tableau de données sur un même sujet : les ventes, les clients, les produits |
| colonne (ou champ) | une information, avec un type fixe : TEXT, INTEGER (entier), REAL (décimal) |
| ligne (ou enregistrement) | un élément : une vente, un client |
SQL, et SQLite dans Python
SQL ne ressemble pas à Python. On ne dit pas comment chercher (pas de boucle) ; on décrit ce qu'on veut, et le SGBD trouve tout seul la façon la plus rapide de l'obtenir :
SELECT produit, quantite FROM ventes WHERE vendeur = 'Paul';
« Sélectionne le produit et la quantité depuis la table ventes, là où le vendeur est Paul. » Presque une phrase en anglais.
SQLite
En Python :
import sqlite3
conn = sqlite3.connect(":memory:") # une base en mémoire, vide
conn.execute("CREATE TABLE eleves (nom TEXT, age INTEGER, ville TEXT)")
conn.execute("INSERT INTO eleves VALUES ('Awa', 19, 'Bafoussam')")
resultat = conn.execute("SELECT * FROM eleves").fetchall()
print(resultat) # [('Awa', 19, 'Bafoussam')]
sqlite3.connect(...)ouvre une connexion à une base : un nom de fichier ("boutique.db") ou":memory:"pour une base temporaire en mémoire ;conn.execute(requete)envoie une requête SQL, écrite dans un texte Python ;.fetchall()récupère toutes les lignes du résultat, sous forme d'une liste de tuples.
SELECT * veut dire « toutes les colonnes ».
Exercice : Ta première base
Complète le code pour :
- créer une table
elevesavec trois colonnes :nom(TEXT),classe(TEXT) etmoyenne(REAL) ; - y insérer trois élèves : Awa en Tle C avec 14.5, Paul en Tle D avec 11.0, Mireille en 1re C avec 16.25 ;
- récupérer toutes les lignes dans
resultat.
Voir une solution
import sqlite3
conn = sqlite3.connect(":memory:")
conn.execute("CREATE TABLE eleves (nom TEXT, classe TEXT, moyenne REAL)")
conn.execute("INSERT INTO eleves VALUES ('Awa', 'Tle C', 14.5)")
conn.execute("INSERT INTO eleves VALUES ('Paul', 'Tle D', 11.0)")
conn.execute("INSERT INTO eleves VALUES ('Mireille', '1re C', 16.25)")
resultat = conn.execute("SELECT * FROM eleves").fetchall()
print(resultat)Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice
La boutique en base de données
Pour la suite du module, les ventes de Mama Brigitte sont fournies dans un fichier boutique.sql : un script SQL qui crée la table ventes et y insère les 42 ventes. Ouvre-le dans l'exercice suivant pour voir à quoi ressemble un vrai script.
Chaque exercice commence par les mêmes lignes, qui créent la base en mémoire à partir du script :
import sqlite3
conn = sqlite3.connect(":memory:")
conn.executescript(open("boutique.sql", encoding="utf-8").read())
executescript exécute plusieurs requêtes à la suite (execute n'en accepte qu'une).
Ensuite, tu n'auras qu'à écrire la requête SQL, entre trois guillemets, dans la variable requete. Les trois guillemets permettent d'écrire un texte sur plusieurs lignes, ce qui rend les longues requêtes lisibles.
Exercice : Les premières ventes
Écris une requête qui sélectionne seulement les colonnes date, produit et vendeur de la table ventes, en ne gardant que les 3 premières lignes.
Pour limiter le nombre de lignes, on ajoute LIMIT 3 à la fin de la requête.
Voir une solution
import sqlite3
conn = sqlite3.connect(":memory:")
conn.executescript(open("boutique.sql", encoding="utf-8").read())
requete = """
SELECT date, produit, vendeur FROM ventes LIMIT 3
"""
resultat = conn.execute(requete).fetchall()
for ligne in resultat:
print(ligne)Dans l'appli, ton code est exécuté et corrigé automatiquement. Faire l'exercice