SQLite



SQLite est un système de gestion de base de données relationnelle (SGBDR) léger et intégré. Il est souvent utilisé pour des applications embarquées ou des projets de petite à moyenne envergure. SQLite est écrit en C et est disponible sous une licence libre. Il est très populaire en raison de sa simplicité, de sa rapidité et de sa capacité à fonctionner sans serveur. SQLite stocke les données dans un fichier unique sur le disque, ce qui le rend facile à déployer et à gérer. Inconvénient : le revers de la médaille de ses avantages : il n'est pas conçu pour gérer des applications à fort volume de transactions ou des environnements multi-serveurs / multi-utilisateurs. Il est donc à réserver pour des applications légères ou des prototypes.

Installation

SQLite est compilé par défaut dans la plupart des distributions Python. Vous pouvez vérifier si SQLite est installé en exécutant la commande suivante dans un terminal :

python -c "import sqlite3; print(sqlite3.sqlite_version)"

Utilisation en python

Le module sqlite3 de Python permet d'intéragir avec les bases de données SQLite. La documentation officielle de Python fournit des informations détaillées sur l'utilisation de ce module : sqlite3 documentation.

Connexion

La fonction connect permet de se "connecter" à une base de données SQLite. Si la base de données n'existe pas, elle sera créée. Si vous précisez ":memory:", une base de données temporaire sera créée en mémoire vive (RAM) et sera détruite à la fermeture de la connexion.

import sqlite3
conn = sqlite3.connect(":memory:")
# conn = sqlite3.connect("data.db")

Par défaut, les bases de données SQLite ne gèrent pas les contraintes d'intégrité référentielle (foreign key). Pour activer cette fonctionnalité pour la connexion courante, vous devez exécuter PRAGMA foreign_keys = ON :

conn.execute('PRAGMA foreign_keys = ON')

De manière générale, l'utilisation de la connexion est faite à travers des curseurs (cursor - un curseur est un objet qui permet d'exécuter des requêtes SQL et de récupérer les résultats), y compris lorsque la requète semble être faite via la connexion comme ci-dessus (dans ce cas, un curseur est automatiquement créé). Vous pouvez créer un curseur en utilisant la méthode cursor() de la connexion :

cursor = conn.cursor()

Exécution de requêtes

Ce curseur peut alors être utilisé pour exécuter des requêtes SQL. Par exemple, pour créer une table :

cursor.execute("""
CREATE TABLE IF NOT EXISTS ingredients (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL
);
""")

Pour insérer des données dans la table :

cursor.execute("""
INSERT INTO ingredients (name)
VALUES ('Mozzarella'),('Tomate'),('Basilic'),
       ('Jambon'),('Olive'),('Oignon'),('Oeuf');
""")
conn.commit()

La méthode commit() de la connexion est utilisée pour valider les modifications apportées à la base de données, car "INSERT" ouvre automatiquement une transaction. Si vous ne l'appelez pas, les modifications ne seront pas enregistrées.

Autre manière de faire : utiliser le manager de contexte (le mot-clé with) pour gérer la connexion, la création du curseur et le commit automatiquement :

with conn:
    conn.execute('''INSERT INTO ingredients (name) VALUES ('Merguez');''')

Récupération de données

Pour récupérer des données, vous pouvez utiliser la méthode fetchall() ou fetchone() du curseur. Par exemple, pour récupérer tous les ingrédients :

cursor.execute('SELECT id,name FROM ingredients')
ingredients = cursor.fetchall()
for ingredient in ingredients:
    print(ingredient) # (1, 'Mozzarella'), ...

fetchall() renvoie une liste de tuple, chaque tuple représentant une ligne de résultat. D'autres méthodes de récupération existent :

  • fetchone() : récupère une seule ligne de résultat. Si aucune ligne n'est trouvée, renvoie None.
  • fetchmany(size) : récupère un nombre spécifié de lignes de résultat. Si aucune ligne n'est trouvée, renvoie une liste vide.

Insertion de données avec des paramètres

Il est impératif de ne pas construire des requêtes SQL en concaténant des chaînes de caractères, car cela peut entraîner des failles de sécurité (injection SQL). Utilisez plutôt des paramètres pour insérer des données :

cursor.execute('INSERT INTO ingredients (name) VALUES (?)', ('Viande hachée',))

Chaque ? est remplacé par la valeur correspondante dans le tuple passé en second argument (pensez à la virgule finale pour le tuple à un seul élément).

Pour insérer plusieurs lignes, vous pouvez utiliser executemany() :

cursor.executemany('INSERT INTO ingredients (name) VALUES (?)',
                   [('Viande hachée',), ('Chèvre',)])

Programme

  • NSI terminale : Système de gestion de bases de données relationnelles
  • NSI terminale : Langage SQL : requètes d'interrogation et de mise à jour d'une base de données