En Python, interagir avec des bases de données est une tâche courante en développement web, analyse de données, auotmatisation ou services backend. L'écosystème propose de nombreuses bibliothèques adaptées à différents types de bases (relationnelles et non relationnelles). Cet article détaille les plus utilisées, avec des exemples concrets et des bonnes pratiques.
Logique fondamentale de l'interaction Python – base de données
Quelle que soit la base ou la bibliothèque, l'interaction suit généralement quatre étapes :
- Connexion : paramètres (hôte, port, utilisateur, mot de passe, nom de la base) via l'API de la bibliothèque.
- Création d'un objet d'exécution : curseur (cursor) ou session pour exécuter les commandes.
- Exécution : requêtes (SELECT, INSERT, UPDATE, DELETE) ou opérations NoSQL.
- Fermeture des ressources : d'abord l'objet d'exécution, puis la connexion, dans cet ordre.
En production, privilégiez les pools de connexions et gérez les exceptions pour éviter les plantages.
Bibliothèques pour bases relationnelles
1. PyMySQL – MySQL
Présentation : client MySQL pur Python, compatible Python 3, multiplateforme. Installez avec pip install pymysql.
Exemple complet (création de table, insertion, requête, mise à jour, suppression) :
import pymysql
from pymysql import Error
def demo_mysql():
config = {
"host": "localhost",
"port": 3306,
"user": "root",
"password": "123456",
"database": "test_db"
}
conn = None
cur = None
try:
conn = pymysql.connect(**config)
cur = conn.cursor()
# Création table
cur.execute("""
CREATE TABLE IF NOT EXISTS members (
id INT AUTO_INCREMENT PRIMARY KEY,
full_name VARCHAR(100) NOT NULL,
age INT,
city VARCHAR(50)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
""")
# Insertion unique
cur.execute("INSERT INTO members (full_name, age, city) VALUES (%s, %s, %s)",
("Alice", 30, "Paris"))
conn.commit()
# Insertion multiple
data = [("Bob", 25, "Lyon"), ("Charlie", 35, "Marseille")]
cur.executemany("INSERT INTO members (full_name, age, city) VALUES (%s, %s, %s)", data)
conn.commit()
# Requête
cur.execute("SELECT * FROM members WHERE age > %s", (28,))
results = cur.fetchall()
for row in results:
print(f"ID: {row[0]}, Nom: {row[1]}, Âge: {row[2]}, Ville: {row[3]}")
# Mise à jour
cur.execute("UPDATE members SET age = %s WHERE full_name = %s", (31, "Alice"))
conn.commit()
# Suppression
cur.execute("DELETE FROM members WHERE full_name = %s", ("Charlie",))
conn.commit()
except Error as e:
print(f"Erreur : {e}")
if conn:
conn.rollback()
finally:
if cur:
cur.close()
if conn and conn.open:
conn.close()
if __name__ == "__main__":
demo_mysql()
Bonnes pratiques : utilisez %s pour éviter les injections SQL, gérez les transactions (commit / rollback), fermez les ressources dans finally, et en production, employez un pool (ex. DBUtils).
2. sqlite3 – SQLite (intégré)
Présentation : bibliothèque standard de Python, aucun安装 nécessaire. Convient aux projets légers, tests ou embarqués. Fichier unique.
import sqlite3
from sqlite3 import Error
def demo_sqlite():
chemin = "exemple.db"
conn = None
cur = None
try:
conn = sqlite3.connect(chemin)
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS livres (
id INTEGER PRIMARY KEY AUTOINCREMENT,
titre TEXT NOT NULL,
auteur TEXT,
prix REAL
)
""")
cur.execute("INSERT INTO livres (titre, auteur, prix) VALUES (?, ?, ?)",
("Python pour tous", "Dupont", 24.99))
cur.executemany("INSERT INTO livres (titre, auteur, prix) VALUES (?, ?, ?)",
[("Java avancé", "Martin", 34.50), ("SQL facile", "Legrand", 19.90)])
conn.commit()
cur.execute("SELECT * FROM livres WHERE prix > ?", (20,))
for row in cur.fetchall():
print(row)
cur.execute("UPDATE livres SET prix = ? WHERE titre = ?", (22.99, "Python pour tous"))
conn.commit()
cur.execute("DELETE FROM livres WHERE auteur = ?", ("Martin",))
conn.commit()
except Error as e:
print(e)
if conn:
conn.rollback()
finally:
if cur:
cur.close()
if conn:
conn.close()
if __name__ == "__main__":
demo_sqlite()
Remarques : utilisez ? comme placeholders (pas %s), l'auto-incrémentation se fait avec INTEGER PRIMARY KEY AUTOINCREMENT, et SQLite ne gère pas bien les écritures simultanées.
3. psycopg2 – PostgreSQL
Présentation : client officiel PostgreSQL, performant. Installez psycopg2-binary pour éviter la compilation. Port par défaut : 5432.
import psycopg2
from psycopg2 import Error
def demo_postgres():
config = {
"host": "localhost",
"port": 5432,
"user": "postgres",
"password": "123456",
"database": "test_pg"
}
conn = None
cur = None
try:
conn = psycopg2.connect(**config)
cur = conn.cursor()
cur.execute("""
CREATE TABLE IF NOT EXISTS employes (
id SERIAL PRIMARY KEY,
nom VARCHAR(50) NOT NULL,
salaire NUMERIC,
extra JSONB
)
""")
cur.execute("INSERT INTO employes (nom, salaire, extra) VALUES (%s, %s, %s)",
("Jean", 45000, '{"service": "IT"}'))
cur.executemany("INSERT INTO employes (nom, salaire, extra) VALUES (%s, %s, %s)",
[("Marie", 52000, '{"service": "RH"}'), ("Pierre", 48000, '{"service": "IT"}')])
conn.commit()
cur.execute("SELECT * FROM employes WHERE extra->>'service' = %s", ("IT",))
for row in cur.fetchall():
print(f"ID: {row[0]}, Nom: {row[1]}, Salaire: {row[2]}, Extra: {row[3]}")
cur.execute("UPDATE employes SET salaire = %s WHERE nom = %s", (47000, "Jean"))
conn.commit()
except Error as e:
print(e)
if conn:
conn.rollback()
finally:
if cur:
cur.close()
if conn:
conn.close()
if __name__ == "__main__":
demo_postgres()
Spécificités : auto-incrémentation avec SERIAL, support natif du JSON/JSONB, placeholders %s comme MySQL.
Bibliothèques pour bases NoSQL
4. pymongo – MongoDB
MongoDB stocke les données sous forme de documents JSON (BSON). Pas de schéma fixe. Installez pip install pymongo.
from pymongo import MongoClient
from pymongo.errors import PyMongoError
def demo_mongo():
client = MongoClient("mongodb://localhost:27017/")
db = client["demo_db"]
collection = db["utilisateurs"]
try:
# Insertion unique
doc1 = {"nom": "Alice", "age": 28, "adresse": {"ville": "Paris", "code": 75001}}
result = collection.insert_one(doc1)
print(f"ID inséré : {result.inserted_id}")
# Insertion multiple
docs = [
{"nom": "Bob", "age": 32, "adresse": {"ville": "Lyon", "code": 69001}},
{"nom": "Charlie", "age": 24, "adresse": {"ville": "Marseille", "code": 13001}}
]
collection.insert_many(docs)
# Requête
for doc in collection.find({"age": {"$gt": 25}}, {"_id": 0}):
print(doc)
# Mise à jour
collection.update_one({"nom": "Alice"}, {"$set": {"age": 29}})
# Suppression
collection.delete_one({"nom": "Charlie"})
except PyMongoError as e:
print(f"Erreur MongoDB : {e}")
finally:
client.close()
if __name__ == "__main__":
demo_mongo()
Conseils : utilisez toujours des opérateurs comme $set, $inc pour les mises à jour, créez des index pour les performances, et fermez la connexion.
5. redis-py – Redis
Redis est un magasin clé-valeur en mémoire. Installez pip install redis. Ne pas oublier decode_responses=True pour obtenir des chaînes.
import redis
def demo_redis():
r = redis.Redis(host="localhost", port=6379, decode_responses=True)
try:
# String
r.set("user:1", "Alice", ex=120)
print(r.get("user:1"))
# Hash
r.hset("product:1", mapping={"name": "Laptop", "price": 999})
print(r.hgetall("product:1"))
# Liste
r.rpush("queue", "task1", "task2")
print(r.lrange("queue", 0, -1))
# Set
r.sadd("tags", "python", "redis", "tutorial")
print(r.smembers("tags"))
finally:
r.close()
if __name__ == "__main__":
demo_redis()
Important : utilisez un pool de connexions en production, définissez des TTL pour éviter les fuites mémoire, et sérialisez les données complexes avec json.
Bonnes pratiques générales
- Gestion des exceptions : capturez toutes les erreurs et effectuez un rollback si nécessaire.
- Pool de connexions : pour MySQL (
DBUtils), MongoDB (intégré), Redis (ConnectionPool). - Injection SQL : toujours utiliser des paramètres (placeholders).
- Journalisation : logguez les événements clés.
- Sécurité : mots de passe, restriction IP, variables d'environnement.
- Opérations par lots : privilégiez les méthodes
executemany,insert_many.
Récapitulatif du choix des bbiliothèques
- MySQL : PyMySQL
- SQLite : sqlite3 (intégré)
- PostgreSQL : psycopg2-binary
- MongoDB : pymongo (ou motor pour asynchrone)
- Redis : redis-py (ou aioredis pour asynchrone)
Ces exemples sont prêts à être exécutés après installation des dépendances. Adaptez les paramètres de connexion à votre environnement.