Une base de données et la mise en place de MySQL : tables, clés, Docker et un pilote
- Expliquer pourquoi on a besoin d’une base de données et quels sont les problèmes de l’enregistrement dans un fichier JSON dans un vrai système
- Définir Table, Row, Column et Primary Key et les reconnaître dans un exemple
- Connaître les types de données de base — INT, VARCHAR, DECIMAL — et NOT NULL
- Traduire un modèle Python (une classe ou un dict) en conception de table
- Expliquer ce qu’est un serveur de base de données, et pourquoi on le fait tourner dans un conteneur Docker
- Lancer MySQL avec docker run, et le redémarrer avec docker start
- Se connecter à la base de données depuis VS Code avec l’extension Database Client et y exécuter du SQL
- Installer le pilote, se connecter depuis Python, et savoir pourquoi le mot de passe ne s’écrit pas dans le code
Dans cette leçon
Cette leçon se compose de deux chapitres, dans le même ordre que les diapositives :
- Chapitre 1 — ce qu’est une base de données : table, ligne, colonne, Primary Key et types de données
- Chapitre 2 — la mise en place de MySQL : Docker, Database Client et un pilote
Chapitre 1 : Ce qu’est une base de données — table, ligne, colonne, Primary Key et types de données
Qu’allons-nous apprendre ?
- Pourquoi on a besoin d’une base de données (Database).
- Ce qu’est une base de données relationnelle (Relational Database).
- Table, Row (ligne), Column (colonne).
- La clé primaire (Primary Key).
- Les types de données (Data Types) de base.
Ici, nous n’apprenons que les bases nécessaires au CRUD : une connexion, une seule table, et créer, lire, mettre à jour et supprimer. Nous n’apprendrons pas JOIN, GROUP BY, HAVING, les sous-requêtes, la normalisation avancée, les index ni les procédures stockées. Vous les apprendrez en profondeur plus tard dans le parcours.
Pourquoi en avons-nous besoin ?
Dans le thème des fichiers, nous avons enregistré des données dans un fichier JSON. Cela fonctionnait pour un seul programme tournant sur notre ordinateur. Sur un vrai serveur, cela casse :
| Un problème avec un fichier JSON | Ce qui se passe |
|---|---|
| Tout ou rien à la lecture | Pour trouver un étudiant parmi un million, on charge tout le fichier en RAM. |
| Tout ou rien à l’écriture | Pour modifier un champ, on réécrit tout le fichier. |
| Deux utilisateurs à la fois | Deux requêtes lisent le fichier, chacune modifie quelque chose, et chacune écrit. La modification de la première est effacée. |
| Un plantage au milieu de l’écriture | Le fichier reste à moitié écrit, et corrompu. |
| Pas de règles | Rien n’empêche deux étudiants avec le même e-mail, ou un champ manquant. |
| Les requêtes | « Tous les étudiants de Haïfa de plus de 20 ans » = une boucle dans notre code, sur toutes les données. |
Une base de données résout tout cela : lire et écrire exactement ce qui est nécessaire, gérer de nombreux utilisateurs en même temps, une protection contre les plantages, des règles imposées dans la base elle-même, et un langage (SQL) pour les requêtes.
Explication à partir des bases
Qu’est-ce qu’une base de données ?
Base de données = un système de stockage organisé des données, qui permet de les enregistrer, de les trouver, de les mettre à jour et de les supprimer de façon efficace et fiable. Le logiciel qui la gère s’appelle un SGBD (DBMS, Database Management System) : MySQL, PostgreSQL, SQLite…
La base de données relationnelle — des tables
Le type le plus répandu est la base de données relationnelle : les données sont organisées en tables, comme une feuille Excel avec des règles strictes.
Table: students
┌────┬────────┬─────┬────────────────┐
│ id │ name │ age │ email │ ← columns (the structure)
├────┼────────┼─────┼────────────────┤
│ 1 │ Dana │ 24 │ dana@mail.com │ ← row = one student
│ 2 │ Avi │ 31 │ avi@mail.com │ ← row
│ 3 │ Noa │ 22 │ noa@mail.com │ ← row
└────┴────────┴─────┴────────────────┘
↑
primary key| Terme | Ce que c’est | En Python (ce que nous connaissons déjà) |
|---|---|---|
| Table | Une collection d’enregistrements du même type | Une classe (le modèle) + une liste de tous les objets |
| Column (colonne) | Un champ, avec un nom et un type fixes | Un attribut |
| Row (ligne, enregistrement) | Un élément | Un objet / un dict |
| Primary Key | Une colonne qui identifie chaque ligne de façon unique | student_id |
Base de données = l’armoire. Table = un tiroir (« étudiants »). Colonnes = le formulaire imprimé sur lequel chaque dossier est construit (nom, âge, e-mail), identique pour tous les dossiers. Ligne = un dossier, d’un étudiant. Primary Key = le numéro au dos du dossier : il ne se répète jamais, et grâce à lui on sort un dossier sans les parcourir tous.
La clé primaire (Primary Key)
Primary Key = une colonne (généralement id) dont la valeur est :
- Unique — deux lignes n’ont pas la même valeur.
- Non vide — chaque ligne doit avoir une valeur.
- Invariable — un identifiant est pour toute la vie de la ligne.
Pourquoi ne pas utiliser le nom ? Parce qu’il y a deux « Dana ». Et l’e-mail ? Parce que les gens changent d’e-mail. Un identifiant numérique que la base de données produit elle-même est le choix sûr. (Vous vous souvenez du Shop qui produisait des identifiants avec max + 1 ? La base de données le fait pour nous, et de façon plus sûre.)
Et c’est exactement le {student_id} du chemin de l’API : GET /students/7 = « apporte la ligne dont la Primary Key vaut 7 ».
Data Types — les types de données de base
Chaque colonne a un type. Dans MySQL (la base de données que nous utiliserons), il existe de nombreux types, mais voici ce dont nous aurons besoin :
| Type SQL | Ce qui est stocké | Python | Exemple |
|---|---|---|---|
| INT | Un nombre entier | int | id, age, quantity |
| DECIMAL(10, 2) | Un nombre décimal exact — 2 chiffres après la virgule | Decimal (comme float, mais exact) | price |
| VARCHAR(100) | Du texte — jusqu’à 100 caractères | str | name, email |
| (pas de vrai BOOLEAN) | Stocker 0/1 dans un INT | bool | is_active |
| NULL | « Aucune valeur » | None | Un champ facultatif vide |
Les contraintes de base (Constraints)
Des règles que la base de données impose. Même s’il y a un bug dans le code, la base refusera :
| Contrainte | Signification |
|---|---|
PRIMARY KEY | L’identifiant unique de la ligne. |
AUTO_INCREMENT | La base produit l’id elle-même, dans l’ordre croissant. |
NOT NULL | Doit être rempli. |
UNIQUE | Pas deux lignes avec la même valeur (par exemple un e-mail). |
C’est comme la validation dans __init__ (le thème POO), sauf que c’est la base de données elle-même qui l’impose : une couche de protection supplémentaire.
SQL — le langage
SQL (Structured Query Language, prononcé « sequel » ou « S-Q-L ») = le langage dans lequel on parle à une base de données relationnelle. Requête (Query) = une commande en SQL. Nous ne rencontrerons que quatre ou cinq commandes :
CREATE TABLE → create the structure (day 3)
INSERT → C - add a row (day 3)
SELECT → R - read rows (day 3)
UPDATE → U - change rows (day 4)
DELETE → D - remove rows (day 4)Syntaxe
Une conception de table (le produit de l’étape de conception, avant tout code). Voici à quoi ressemble la conception de la table students :
Table: students
| column | type | constraints |
|--------|--------------|-----------------------------|
| id | INT | AUTO_INCREMENT PRIMARY KEY |
| name | VARCHAR(100) | NOT NULL |
| age | INT | NOT NULL |
| email | VARCHAR(100) | NOT NULL UNIQUE |Et voici la commande SQL qui la crée (nous l’écrirons et l’exécuterons dans les leçons suivantes ; ici, c’est seulement pour voir où nous allons) :
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INT NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE
);Premier exemple de code
D’une classe Python à une conception de table. La classe Product du thème POO :
class Product:
def __init__(self, sku, name, price, stock=0):
...La traduction :
| Attribut en Python | Colonne | Type | Contraintes | Pourquoi |
|---|---|---|---|---|
| — | id | INT | AUTO_INCREMENT PRIMARY KEY | Un identifiant interne stable |
sku | sku | VARCHAR(20) | NOT NULL UNIQUE | Unique, obligatoire |
name | name | VARCHAR(100) | NOT NULL | Obligatoire |
price | price | DECIMAL(10, 2) | NOT NULL | Un nombre décimal exact |
stock | stock | INT | NOT NULL DEFAULT 0 | Un nombre entier, 0 par défaut |
Analyse du code ligne par ligne
| Décision | Raisonnement |
|---|---|
Ajouter id alors qu’il y a un sku | sku est un identifiant métier qui peut changer (changement de marque). id est un identifiant technique qui ne change jamais. Il est courant de garder les deux. |
sku avec UNIQUE | La règle « le SKU est unique » est imposée dans la base de données, même si un autre code oublie de la vérifier. |
price en DECIMAL(10, 2) | Un prix avec des agorot (les centimes du shekel). DECIMAL stocke le nombre exactement — sans les problèmes d’arrondi de float (0.1 + 0.2). |
| Ce qui n’entre pas dans la table | Les méthodes (take, restock) sont du comportement, et elles vivent dans le code. La base de données ne stocke que des données. |
Un autre exemple
De dicts à une table, et des types « désordonnés ». Des données arrivées d’un fichier JSON :
students = [
{"name": "Dana", "age": 24, "email": "dana@mail.com", "phone": "050-1234567"},
{"name": "Avi", "age": "31", "email": "avi@mail.com"},
{"name": "Noa", "age": 22, "email": "dana@mail.com", "phone": None},
]Des questions de conception :
phonen’apparaît que dans certaines lignes. → une colonne sansNOT NULL. Quand il n’y a pas de valeur, NULL est stocké (Noneen Python).- L’
aged’Avi vaut"31"(une chaîne). → la colonne estINT. Dans le code, nous convertirons avecint(...)avant d’enregistrer (ou Pydantic convertira, dans le thème de l’API des étudiants). - Noa et Dana ont le même e-mail. → avec
UNIQUEsuremail, la base refusera d’enregistrer Noa. C’est exactement ce que nous voulons (et nous gérerons cette erreur dans les leçons suivantes). - Il n’y a pas d’
id. →AUTO_INCREMENT: la base donnera 1, 2, 3.
| column | type | constraints |
|--------|--------------|----------------------------|
| id | INT | AUTO_INCREMENT PRIMARY KEY |
| name | VARCHAR(100) | NOT NULL |
| age | INT | NOT NULL |
| email | VARCHAR(100) | NOT NULL UNIQUE |
| phone | VARCHAR(20) | (nullable) |Pourquoi phone est-il un VARCHAR et non un INT ? Parce que 050-1234567 contient un tiret, et un numéro de téléphone qui commence par 0 perdrait le zéro en INT. Règle : un « nombre » sur lequel on ne fait pas de calcul (un téléphone, un code postal, un numéro d’identité) → VARCHAR.
Erreur courante
Erreur 1 : une Primary Key « naturelle » qui peut changer ou se répéter. Un nom, un e-mail, un numéro de téléphone. Le jour où Dana change d’e-mail, tous ceux qui pointaient vers elle par e-mail la « perdent ». Un id numérique produit par la base de données.
Erreur 2 : stocker une liste dans une seule colonne.
| id | name | grades |
| 1 | Dana | "90,85,70" |On ne peut pas calculer une moyenne en SQL, on ne peut pas chercher « tous ceux qui ont eu 90 », et il est difficile de mettre à jour une seule note. Dans le monde relationnel, les notes sont une table séparée (grades, avec un student_id). Vous l’apprendrez en profondeur plus tard dans le parcours (les relations entre tables et JOIN). Ici, nous travaillerons avec une seule table et des champs simples.
Erreur 3 : renoncer à NOT NULL et UNIQUE, « parce que le code vérifie ». Le code vérifie aujourd’hui. Demain, quelqu’un écrira un script d’import qui contourne le code, ou il y aura un bug. La base de données est la dernière ligne de défense.
Erreur 4 : croire que SQL est « un programme ». SQL est un langage déclaratif : on dit ce que l’on veut (« tous les étudiants de Haïfa »), et non comment le trouver (pas de boucles). C’est la base de données qui décide comment l’exécuter efficacement.
Résumé
- Une base de données résout les problèmes du fichier JSON : lecture et écriture ciblées, de nombreux utilisateurs en même temps, résistance aux plantages, règles et requêtes.
- Une base relationnelle = des tables. Table ≈ une classe + tous les objets. Column ≈ un attribut (avec un type). Row ≈ un objet.
- Primary Key = un identifiant unique, non vide et invariable. Généralement
id INT AUTO_INCREMENT PRIMARY KEY. - Les types dans MySQL : INT, DECIMAL, VARCHAR, et NULL (=
None). Un booléen se stocke en 0/1. Un téléphone et un code postal se stockent en VARCHAR. - Les contraintes : NOT NULL, UNIQUE. La base impose les règles même quand le code se trompe.
- SQL = un langage déclaratif. Ici : CREATE TABLE, INSERT, SELECT, UPDATE, DELETE, et c’est tout.
Documentation officielle
Chapitre 2 : La mise en place de MySQL — Docker, Database Client et un pilote
Qu’allons-nous apprendre ?
- Ce qu’est un serveur de base de données, et pourquoi nous travaillerons avec MySQL.
- Ce qu’est un conteneur, et comment faire tourner MySQL dans Docker — avec une seule commande.
- Comment voir la base de données depuis VS Code avec l’extension Database Client.
- Ce qu’est un pilote (Driver), et comment Python se connecte à MySQL.
- Où garder les informations de connexion — et pourquoi pas dans le code.
Pourquoi en avons-nous besoin ?
Avant d’écrire un seul INSERT, il faut répondre à des questions de « plomberie » : où tourne la base de données ? Comment notre code y accède-t-il ? Quelles sont les informations de connexion ? Dans un vrai travail, la première chose que l’on reçoit dans un nouveau projet est exactement cela : « voici les informations de connexion à la base de données ». Il faut savoir quoi en faire.
Explication à partir des bases
Une base de données est un serveur
MySQL est un serveur de base de données : un programme séparé (un processus — souvenez-vous du thème sur le système d’exploitation !) qui tourne en permanence et écoute sur un port — pour MySQL, c’est le port 3306. Notre code n’ouvre pas un fichier — il se connecte par le réseau au serveur, exactement comme un navigateur qui se connecte à un site web (le thème des réseaux : IP + port).
| MySQL (un serveur de base de données) | |
|---|---|
| Où | Un processus séparé qui écoute sur le port 3306 |
| Comment on se connecte | Par le réseau : hôte, port, utilisateur, mot de passe et le nom de la base |
| Qui se connecte | Plusieurs programmes et serveurs — en même temps |
| Où on le trouve dans le monde | Les sites web et les systèmes de toutes tailles. PostgreSQL et SQL Server fonctionnent aussi ainsi |
Pourquoi Docker ?
Installer MySQL directement sur l’ordinateur est un long processus : un assistant d’installation, des mots de passe, un service qui tourne en arrière-plan, et des réglages différents entre Windows et Mac. Et ce qui fonctionne pour l’un — ne fonctionne pas toujours pour l’autre.
Docker (que nous avons installé la première semaine) résout cela : il fait tourner des programmes prêts à l’emploi dans un conteneur.
- Image — le modèle : « MySQL version 8.4, prêt à l’emploi ». On la télécharge une fois.
- Conteneur (Container) — une copie en cours d’exécution de l’image. Isolé du reste de l’ordinateur, avec tout ce dont le programme a besoin.
Un conteneur maritime a le même aspect sur chaque navire et dans chaque port — quel que soit son contenu. Il en va de même pour un conteneur Docker : le même MySQL, avec les mêmes réglages, tourne exactement de la même façon pour tous les étudiants, sur tout système d’exploitation.
Database Client — la base de données avec une interface
On peut voir et utiliser MySQL sans une seule ligne de code, avec une extension de VS Code nommée Database Client (de Weijan Chen). Elle affiche un arbre des bases et des tables, ouvre une table comme un tableur, et exécute du SQL en affichant le résultat sous forme de tableau. Nous l’utiliserons tout au long de ces thèmes pour voir ce que notre code a fait dans la base de données.
Le pilote — l’interprète
Notre code est écrit en Python. MySQL parle son propre « protocole » (le thème des réseaux : protocole = règles de communication). Il faut un intermédiaire qui traduit : un pilote (Driver, aussi appelé Database Connector) = une bibliothèque qui sait :
- Se connecter à un serveur de base de données d’un certain type.
- Lui envoyer des commandes SQL.
- Renvoyer les résultats sous forme de données Python (tuples, int, str).
Pour MySQL, nous utiliserons le pilote officiel : mysql-connector-python. On l’installe avec pip, et dans le code on écrit import mysql.connector.
Votre appareil (le code Python) a une prise israélienne, et la prise murale (la base de données) est américaine. Le pilote = l’adaptateur. Chaque type de prise a son propre adaptateur, mais l’appareil lui-même ne change pas.
Les informations de connexion — et pas dans le code !
Pour se connecter à MySQL, il faut cinq informations :
| Information | La nôtre | Ce que c’est |
|---|---|---|
host | localhost | Où se trouve le serveur — notre ordinateur |
port | 3306 | Le port de MySQL |
user | root | Le nom d’utilisateur |
password | kodkod | Le mot de passe que nous avons défini dans le conteneur |
database | school | Quelle base de données à l’intérieur du serveur |
Dans un vrai projet, il y a ici un vrai mot de passe. S’il est écrit dans le code et que le code est monté sur GitHub, il a fuité (souvenez-vous des secrets du thème Git !). La pratique professionnelle :
- Les informations de connexion sont conservées dans des variables d’environnement (Environment Variables), ou dans un fichier
.envqui est dans.gitignore. - Le code les lit :
os.environ.get("DB_PASSWORD").
Syntaxe
Faire tourner MySQL dans un conteneur — une seule commande, une seule fois (dans PowerShell ; sur Mac, remplacez le ` par \) :
docker run --name kodkod-mysql `
-e MYSQL_ROOT_PASSWORD=kodkod `
-e MYSQL_DATABASE=school `
-p 3306:3306 -d mysql:8.4| Partie | Signification |
|---|---|
docker run | Crée et démarre un nouveau conteneur |
--name kodkod-mysql | Un nom pour le conteneur, pour pouvoir y faire référence |
-e MYSQL_ROOT_PASSWORD=kodkod | Une variable d’environnement : le mot de passe de l’utilisateur root |
-e MYSQL_DATABASE=school | Une variable d’environnement : une base nommée school créée automatiquement |
-p 3306:3306 | Le port 3306 de notre ordinateur mène au MySQL à l’intérieur du conteneur |
-d | Tourne en arrière-plan (detached), et le terminal reste libre |
mysql:8.4 | L’image : MySQL version 8.4 |
Des commandes utiles :
docker ps # which containers are running now
docker start kodkod-mysql # start it again (after a restart of the computer)
docker stop kodkod-mysql # stop it (the data is kept)Se connecter depuis Python :
import mysql.connector
connection = mysql.connector.connect(
host="localhost",
port=3306,
user="root",
password="kodkod",
database="school",
)
connection.close()mysql.connector.connect(...)— ouvre une connexion réseau au serveur. Si le serveur ne tourne pas — une erreur.port=3306est la valeur par défaut, on peut l’omettre.
Premier exemple de code
Mettre en place la base de données de ces thèmes, étape par étape.
1. Lancez MySQL (Docker Desktop doit être ouvert) :
docker run --name kodkod-mysql `
-e MYSQL_ROOT_PASSWORD=kodkod `
-e MYSQL_DATABASE=school `
-p 3306:3306 -d mysql:8.4
docker psAu premier lancement, Docker télécharge l’image (quelques minutes). docker ps montre que le conteneur tourne :
CONTAINER ID IMAGE STATUS PORTS NAMES
ffaa661f5047 mysql:8.4 Up 10 seconds 0.0.0.0:3306->3306/tcp kodkod-mysql2. Connectez-vous depuis VS Code :
- L’onglet Extensions → cherchez Database Client (de Weijan Chen) → Install.
- Une icône de base de données apparaît dans la barre latérale. Cliquez dessus → + (Create Connection) → choisissez MySQL.
- Remplissez : Host
127.0.0.1, Port3306, Usernameroot, Passwordkodkod, Databaseschool→ Connect. - La connexion apparaît dans l’arbre, et à l’intérieur la base
school— encore sans tables.
3. Un projet Python :
mkdir ~\dev\kodkod6\week-4\school-db
cd ~\dev\kodkod6\week-4\school-db
git init
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install mysql-connector-python.gitignore :
__pycache__/
.venv/
.envsetup_db.py :
import os
import mysql.connector
connection = mysql.connector.connect(
host="localhost",
port=3306,
user="root",
password=os.environ.get("DB_PASSWORD", "kodkod"),
database="school",
)
print("Connected:", connection.is_connected())
print("Server version:", connection.server_info)
connection.close()
print("Connected after close:", connection.is_connected())Sortie :
Connected: True
Server version: 8.4.11
Connected after close: FalseAnalyse du code ligne par ligne
| Code | Explication |
|---|---|
import mysql.connector | Le pilote. Installé avec pip install mysql-connector-python. |
host="localhost", port=3306 | Où est le serveur : notre ordinateur, sur le port que nous avons ouvert avec -p 3306:3306. |
user="root" | L’utilisateur principal de MySQL. |
os.environ.get("DB_PASSWORD", "kodkod") | Le mot de passe — depuis une variable d’environnement si elle a été définie, sinon la valeur par défaut de l’environnement d’apprentissage. |
database="school" | La base créée avec -e MYSQL_DATABASE=school. |
connection.is_connected() | True — la connexion est ouverte. |
connection.server_info | La version du serveur MySQL. Votre numéro peut être différent. |
connection.close() | Ferme la connexion (dans la leçon suivante : pourquoi c’est important). |
Pas de *.db dans .gitignore | Les données se trouvent dans le conteneur, pas dans le dossier du projet. Seul le code qui crée la structure entre dans Git. |
Un autre exemple
Le conteneur après le redémarrage de l’ordinateur
Après un redémarrage, Docker Desktop se lance — mais le conteneur ne tourne pas. Relancer docker run ? Non — le nom kodkod-mysql est déjà pris :
docker: Error response from daemon: Conflict. The container name "/kodkod-mysql" is already in use by container ...Le conteneur existe, il est seulement arrêté. Démarrez-le :
docker start kodkod-mysqlToutes les données ont été conservées — les tables et les lignes restent dans le conteneur jusqu’à ce que vous le supprimiez (docker rm).
Quand le serveur ne tourne pas
Si Docker Desktop est fermé ou si le conteneur est arrêté, la connexion depuis Python échoue :
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on 'localhost:3306' (Errno 10061: No connection could be made because the target machine actively refused it)Can't connect = personne n’écoute sur le port 3306. Vérifiez avec docker ps, et démarrez-le avec docker start kodkod-mysql.
Erreur courante
Erreur 1 : Docker Desktop n’est pas ouvert.
failed to connect to the docker API ... The system cannot find the file specified.Les commandes docker communiquent avec Docker Desktop. Ouvrez-le, attendez la fin du démarrage, et réessayez.
Erreur 2 : le port est occupé.
Bind for 0.0.0.0:3306 failed: port is already allocatedQuelque chose tourne déjà sur le port 3306 — généralement un MySQL installé autrefois directement sur l’ordinateur. Vous pouvez utiliser un autre port sur notre ordinateur : -p 3307:3306, puis vous connecter avec port=3307.
Erreur 3 : un mot de passe de base de données dans du code qui monte sur GitHub.
connection = mysql.connector.connect(host="prod-db.company.com", user="admin", password="MyRealPassword123")Même si vous le supprimez dans le Commit suivant, le mot de passe reste dans l’historique (souvenez-vous du thème Git !). Des variables d’environnement / un .env dans .gitignore. (Notre mot de passe kodkod ne sert qu’à un environnement d’apprentissage local.)
Résumé
- MySQL = un serveur de base de données : un processus qui écoute sur le port 3306, et auquel on se connecte par le réseau.
- Docker fait tourner MySQL dans un conteneur — avec une seule commande, et la même pour tous.
docker runune fois, puisdocker start kodkod-mysql. - Database Client (une extension de VS Code) = une interface vers la base : un arbre des tables, l’exécution de SQL et les résultats sous forme de tableau.
- Pilote = une bibliothèque qui traduit entre Python et la base. Pour MySQL :
mysql-connector-python(import mysql.connector). - Cinq informations de connexion :
host,port,user,password,database. - Les mots de passe ne s’écrivent pas dans le code : des variables d’environnement ou un
.envdans.gitignore.
Documentation officielle
Exercices
Les exercices n’utilisent que ce qui a été vu dans cette leçon et les précédentes. Essayez d’abord seul, et n’ouvrez la solution qu’ensuite.
Exercice 1: Table, ligne, colonne
id | name | age | email
---+------+-----+---------------
1 | Dana | 24 | dana@mail.com
2 | Avi | 31 | avi@mail.com- Combien de lignes et combien de colonnes y a-t-il dans la table ?
- Que décrit chaque ligne, et que décrit chaque colonne ?
- Quelle colonne convient pour être la Primary Key, et pourquoi pas
name?
Afficher la solution
- 2 lignes et 4 colonnes.
- Chaque ligne (Row) est un étudiant — un enregistrement. Chaque colonne (Column) est un champ, d’un type fixe, que possèdent tous les étudiants.
id— il est unique, ne change jamais, et est créé automatiquement.namene convient pas : il peut y avoir deux étudiantes nommées Dana, et un nom peut changer.
Exercice 2: Types et contraintes
Écrivez la commande SQL qui crée une table students avec :
id— un nombre entier, une Primary Key, créé automatiquement ;name— du texte, obligatoire ;age— un nombre entier, obligatoire ;email— du texte, obligatoire et unique.
Afficher la solution
CREATE TABLE students (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
age INT NOT NULL,
email VARCHAR(100) NOT NULL UNIQUE
);INT/VARCHAR(100)— le type de chaque colonne : un nombre entier, et un texte de 100 caractères au plus.NOT NULL— ne peut pas rester vide.UNIQUE— pas deux étudiants avec le même e-mail.AUTO_INCREMENT— la base choisit l’idelle-même.
Exercice 3: Qu’est-ce que la base détecterait ?
students = [
{"name": "Dana", "age": 24, "email": "d@x.com"},
{"name": "Avi", "age": 24, "email": None},
{"name": "Noa", "age": 22, "email": "d@x.com"},
]Lesquelles de ces données la table students de l’exercice précédent rejetterait-elle, et à cause de quelle contrainte ? Et pourquoi personne ne les a arrêtées dans la liste Python ?
Afficher la solution
- Avi — l’e-mail vaut
None→ rejeté à cause deNOT NULL. - Noa — le même e-mail que Dana → rejetée à cause de
UNIQUE. - Dana — valide.
Une liste Python n’a aucune règle : n’importe quelle valeur y entre. Dans une base de données, les règles sont définies une seule fois, dans la table, et s’appliquent à tous ceux qui y écrivent — depuis n’importe quel programme.
Exercice 4: Démarrer MySQL
- Que fait chaque partie de la commande suivante ?
- Comment vérifier que le conteneur tourne ?
- Comment le redémarrer après le redémarrage de l’ordinateur — sans en créer un nouveau ?
docker run --name kodkod-mysql -e MYSQL_ROOT_PASSWORD=kodkod -e MYSQL_DATABASE=school -p 3306:3306 -d mysql:8.4Afficher la solution
| Partie | Signification |
|---|---|
docker run | Crée et démarre un nouveau conteneur |
--name kodkod-mysql | Un nom pour le conteneur, pour pouvoir y faire référence |
-e MYSQL_ROOT_PASSWORD=kodkod | Le mot de passe de l’utilisateur root |
-e MYSQL_DATABASE=school | Une base nommée school créée automatiquement |
-p 3306:3306 | Le port 3306 de notre ordinateur mène au MySQL du conteneur |
-d | Tourne en arrière-plan, et le terminal reste libre |
mysql:8.4 | L’image : MySQL version 8.4 |
docker ps— affiche les conteneurs qui tournent en ce moment.docker start kodkod-mysql— démarre le conteneur existant. Ses données sont conservées. Relancerdocker runéchouerait, car le nom est déjà pris.
Exercice 5: Une première connexion
Écrivez un code qui se connecte à la base school du conteneur, affiche si la connexion est active, la ferme, et affiche à nouveau.
Résultat attendu :
Connected: True
Connected after close: FalseAfficher la solution
import mysql.connector
connection = mysql.connector.connect(
host="localhost",
port=3306,
user="root",
password="kodkod",
database="school",
)
print("Connected:", connection.is_connected())
connection.close()
print("Connected after close:", connection.is_connected())Connected: True
Connected after close: Falsemysql.connector.connect ouvre une connexion réseau au serveur MySQL du conteneur. Si le conteneur ne tourne pas — vous obtenez une erreur : Can't connect to MySQL server.