Création et manipulation d'une base de données avec SQLite

Une base de données est entièrement contenue dans un fichier. Il suffit de démarrer une session SQLite en indiquant un nom de fichier pour créer une nouvelle base ou rouvrir une base existante :

$ sqlite3 /tmp/mabase.sqlite

On peut alors saisir des requêtes SQL habituelles :

sqlite> CREATE TABLE livres (titre VARCHAR(30), auteur INTEGER);
sqlite> CREATE TABLE auteurs (nom VARCHAR(20), prenom VARCHAR(20), id INTEGER PRIMARY KEY);
sqlite> INSERT INTO livres (titre, auteur) VALUES ('The Art of Computer Programming', 1);
sqlite> INSERT INTO livres (titre, auteur) VALUES ('Tintin au Congo', 2);
sqlite> INSERT INTO livres (titre, auteur) VALUES ('The TeXbook', 1);
sqlite> INSERT INTO auteurs (nom, prenom, id) VALUES ('Knuth', 'Donald', 1);
sqlite> INSERT INTO auteurs (nom, prenom, id) VALUES ('Herge', NULL, 2);

Lorsque l'on fait des requêtes SELECT, il est pratique d'avoir une présentation des tables en colonnes et avec des titres de colonnes. Cela s'active avec les commandes suivantes :

sqlite> .mode column
sqlite> .header on

On obtient alors un résultat sympathique :

sqlite> SELECT nom, prenom, titre FROM livres, auteurs WHERE livres.auteur = auteurs.id;
nom         prenom      titre
- - - - -   - - - - -   - - - - - - - - - - - - - - - -
Knuth       Donald      The Art of Computer Programming
Herge                   Tintin au Congo
Knuth       Donald      The TeXbook

Il est également possible de lancer des requêtes au coup par coup, sans ouvrir de session interactive :

$ sqlite3 /tmp/mabase.sqlite "SELECT nom, COUNT(*) FROM auteurs, livres WHERE auteurs.id = livres.auteur GROUP BY livres.auteur"
Knuth|2
Herge|1

Pour terminer, soulignons que l'implémentation SQL proposée par SQLite est assez complète ; elle comprend notamment les sous-requêtes, les triggers, les transactions.

Accès depuis Python

La bibliothèque sqlite3 est présente à partir de Python 2.5. Son utilisation est très simple, et ne déroutera pas les adeptes de PHP/MySQL.

L'accès aux données se base sur la notion de curseur, qui permet d'effectuer des requêtes, et éventuellement de parcourir leur résultat. Le squelette de base pour l'accès à une base de données est le suivant :

import sqlite3;

conn = sqlite3.connect("/tmp/mabase.sqlite")  # ouverture de la base
conn.row_factory = sqlite3.Row                # accès facile aux colonnes
c = conn.cursor()                             # obtention d'un curseur

#
# utilisation de la base
#

c.close()

La ligne conn.row_factory = sqlite3.Row n'est pas obligatoire, mais elle permet un accès facile aux colonnes des résultats par leurs noms, comme en PHP (c["nom"] plutôt que c[0]...).

Pour effectuer une requête, on utilise la méthode execute, puis on se sert du curseur pour parcourir les résultats dans le cas d'un SELECT :

c.execute("SELECT nom, titre FROM livres, auteurs WHERE livres.auteur = auteurs.id")

for ligne in c:
        print ligne
        print ligne["nom"], "a ecrit", ligne["titre"]

Si la requête apporte une modification à la base, celle-ci n'est effective qu'après exécution de la méthode commit de l'objet connexion :

c.execute("INSERT INTO auteurs VALUES  (?, ?, ?)", ("Vernes", "Jules", 3))
conn.commit()

Notez que cet appel à execute utilise les fonctionnalités de substitution de texte du sous-système de bases de données de Python. On peut indiquer un nombre quelconque de points d'interrogation dans la requête, et ils sont remplacés par les éléments du tuple fourni en deuxième argument. C'est ici purement anecdotique, mais cela peut s'avérer très pratique.

Conclusion

J'espère que ce billet montre à quel point il est facile d'utiliser SQLite, en particulier depuis Python. Il n'y a désormais plus aucune excuse pour s'embêter à gérer soi-même des fichiers textes pour stocker quelques données. Pour plus d'informations :