Modification des données et définition des tables

Vidéo : le langage SQL, interroger et modifier une table (5 min 33)
Objectifs et prérequis

Prérequis : bases de données relationnelles (contraintes d’intégrité), requêtes de sélection SQL

À l’issue de ce chapitre, vous saurez :

  • insérer des données dans une table avec INSERT INTO ... VALUES ;
  • modifier des données existantes avec UPDATE ... SET ... WHERE ;
  • supprimer des lignes avec DELETE FROM ... WHERE ;
  • créer une table avec CREATE TABLE, en y déclarant les contraintes d’intégrité, et la supprimer avec DROP TABLE ;
  • interagir avec une base SQLite depuis Python grâce au module sqlite3.

Insertion de données : INSERT

L’ordre INSERT INTO ajoute un nouveau n-uplet (une nouvelle ligne) dans une table.

Syntaxe générale :

INSERT INTO nom_table (attribut1, attribut2, ...)
VALUES (valeur1, valeur2, ...);

Exemple. Ajouter un nouveau produit dans la table Produits :

INSERT INTO Produits (id, nom, categorie, prix, stock)
VALUES (9, 'Règle 30 cm', 'Papeterie', 1.80, 120);

Les valeurs doivent respecter les types des attributs et les contraintes d’intégrité. Si l’id existe déjà ou si le prix est négatif (avec un CHECK), le SGBD refuse l’insertion.

Modification de données : UPDATE

L’ordre UPDATE modifie les valeurs d’un ou plusieurs attributs pour les lignes qui vérifient une condition.

Syntaxe générale :

UPDATE nom_table
SET attribut1 = nouvelle_valeur1, attribut2 = nouvelle_valeur2
WHERE condition;

Exemple. Le prix du Cahier A4 passe à 2.80 :

UPDATE Produits
SET prix = 2.80
WHERE nom = 'Cahier A4';

Attention. Sans clause WHERE, toutes les lignes de la table sont modifiées :

UPDATE Produits
SET stock = 0;
-- Met TOUT le stock à 0 ! Probablement pas souhaitable.

Suppression de données : DELETE

L’ordre DELETE supprime les lignes qui vérifient une condition.

Syntaxe générale :

DELETE FROM nom_table
WHERE condition;

Exemple. Supprimer les produits dont le stock est nul :

DELETE FROM Produits
WHERE stock = 0;

Attention. Sans clause WHERE, toutes les lignes sont supprimées (la table reste, mais vide).

La suppression peut être refusée si des lignes d’une autre table référencent la ligne à supprimer via une clé étrangère (contrainte de référence).

Création d’une table : CREATE TABLE

L’ordre CREATE TABLE définit la structure d’une nouvelle table : le nom de chaque attribut, son type et les contraintes associées.

CREATE TABLE Eleves (
    id_eleve    INTEGER PRIMARY KEY,
    nom         TEXT NOT NULL,
    prenom      TEXT NOT NULL,
    classe      TEXT,
    annee_naissance INT CHECK (annee_naissance >= 2000)
);

Types de données courants en SQLite

TypeDescription
INT ou INTEGEREntier
REALNombre à virgule flottante
TEXTChaîne de caractères
DATEDate (stockée comme texte au format 'AAAA-MM-JJ' en SQLite)

Déclarer les contraintes

Les contraintes d’intégrité s’écrivent dans CREATE TABLE, à la suite d’un attribut ou en fin de définition :

Mot-cléContrainteEffet
NOT NULLDomaineInterdit les valeurs vides
CHECK (condition)DomaineRestreint les valeurs acceptées
UNIQUERelationInterdit les doublons sur un attribut qui n’est pas la clé primaire
PRIMARY KEYRelationDésigne la clé primaire : unicité et non-nullité
FOREIGN KEY (attribut) REFERENCES Table(attribut)RéférenceImpose que la valeur désigne une ligne existante de l’autre table

La table Eleves ci-dessus déclare déjà une clé primaire, deux attributs NOT NULL et un CHECK. La table Emprunts déclare en plus deux clés étrangères :

CREATE TABLE Emprunts (
    id_emprunt      INTEGER PRIMARY KEY,
    id_livre        INT NOT NULL,
    id_adherent     INT NOT NULL,
    date_emprunt    TEXT NOT NULL,
    date_retour     TEXT,
    FOREIGN KEY (id_livre) REFERENCES Livres(id_livre),
    FOREIGN KEY (id_adherent) REFERENCES Adherents(id_adherent)
);

Trois particularités de SQLite, le SGBD utilisé en TP :

  • SQLite ne vérifie les clés étrangères qu’après la commande PRAGMA foreign_keys = ON;, à exécuter au début de chaque connexion ;
  • dans une table ordinaire, SQLite accepte une valeur vide dans une clé primaire, sauf si elle est déclarée INTEGER PRIMARY KEY ou NOT NULL : c’est pourquoi les exemples écrivent INTEGER, et non INT, devant PRIMARY KEY ;
  • SQLite accepte une valeur d’un autre type que celui de l’attribut : la chaîne 'vingt-cinq' est rangée telle quelle dans un attribut INT, sauf si la table est déclarée STRICT.

Suppression d’une table : DROP TABLE

DROP TABLE nom_table;

Cette opération est irréversible : la table et toutes ses données sont supprimées.

Interagir avec Python : le module sqlite3

Python intègre le module sqlite3 qui permet de manipuler une base de données SQLite sans installer de logiciel supplémentaire.

Se connecter à une base

import sqlite3

conn = sqlite3.connect("ma_base.db")
cursor = conn.cursor()

Si le fichier ma_base.db n’existe pas, il est créé automatiquement.

Exécuter des requêtes

# Créer une table
cursor.execute("""
    CREATE TABLE IF NOT EXISTS Eleves (
        id_eleve    INTEGER PRIMARY KEY,
        nom         TEXT NOT NULL,
        prenom      TEXT NOT NULL,
        classe      TEXT
    )
""")

# Insérer des données
cursor.execute("""
    INSERT INTO Eleves (id_eleve, nom, prenom, classe)
    VALUES (1, 'Dupont', 'Marie', 'Terminale A')
""")

# Valider les modifications
conn.commit()

L’appel à conn.commit() est indispensable pour enregistrer les modifications dans le fichier. Sans cet appel, les données sont perdues à la fermeture.

Récupérer les résultats

cursor.execute("SELECT nom, prenom FROM Eleves WHERE classe = 'Terminale A'")

resultats = cursor.fetchall()
for ligne in resultats:
    print(ligne)
# ('Dupont', 'Marie')
  • cursor.fetchone() renvoie un seul tuple (la ligne suivante) ;
  • cursor.fetchall() renvoie une liste de tous les tuples.

Fermer la connexion

conn.close()

Cela libère les ressources. Attention : close() n’enregistre pas les modifications ; il faut appeler conn.commit() avant de fermer la connexion.

Vérifiez votre compréhension
  1. Quelle est la différence entre INSERT et UPDATE ?
    RéponseINSERT ajoute une nouvelle ligne dans la table. UPDATE modifie les valeurs d'une ou plusieurs lignes existantes. INSERT crée un nouveau n-uplet, UPDATE change un n-uplet déjà présent.
  2. Que se passe-t-il si on écrit DELETE FROM Produits; sans clause WHERE ?
    RéponseToutes les lignes de la table Produits sont supprimées. La table existe toujours (sa structure est conservée), mais elle est vide. C'est pourquoi il faut toujours vérifier la clause WHERE avant d'exécuter un DELETE.
  3. Pourquoi faut-il appeler conn.commit() en Python après un INSERT ?
    RéponseSans conn.commit(), les modifications restent en mémoire mais ne sont pas écrites dans le fichier de la base de données. Si on ferme la connexion sans commit, les données insérées sont perdues.
L'essentiel à retenir
  • INSERT INTO ... VALUES ajoute de nouvelles lignes dans une table.
  • UPDATE ... SET ... WHERE modifie des valeurs existantes (attention sans WHERE : toutes les lignes sont modifiées).
  • DELETE FROM ... WHERE supprime des lignes (attention sans WHERE : toutes les lignes sont supprimées).
  • CREATE TABLE définit la structure d’une table avec ses types et contraintes ; DROP TABLE la supprime définitivement.
  • En Python, le module sqlite3 permet de se connecter à une base, d’exécuter des requêtes avec cursor.execute(), de récupérer les résultats avec fetchall(), et d’enregistrer les modifications avec conn.commit().