SQLAlchemy : pilote ta base de données en Python sans écrire une ligne de SQL

SQLAlchemy : pilote ta base de données en Python sans écrire une ligne de SQL

De quoi avez-vous besoin

Version de Python

3.x

Packages

  • {"nom":"SQLAlchemy","version":"2.0.52"}

Difficulté

Intermédiaire

Tu as déjà croisé un script Python qui trimballe son SQL dans des chaînes de caractères ? Un f"SELECT * FROM users WHERE name = '{nom}'" qui fonctionne très bien, jusqu'au jour où un nom contient une apostrophe — ou pire, jusqu'au jour où quelqu'un y glisse une injection. SQLAlchemy règle le problème à la racine. Au lieu d'écrire du SQL à la main, tu décris tes tables avec de simples classes Python, et l'ORM se charge de traduire tes intentions en SQL propre, paramétré et sécurisé.

Résultat : ton code est lisible, tes données sont typées, et tu passes de SQLite à PostgreSQL en changeant une seule ligne. On y va.

Prérequis

Rien de plus que Python 3 et la bibliothèque sqlalchemy. SQLite est intégré à Python, donc tu n'as même pas besoin d'installer un serveur de base de données pour suivre ce tutoriel.

bash
pip install sqlalchemy

Étape 1 — Le moteur, ton point d'entrée

Tout commence par un Engine, l'objet qui gère la connexion à ta base. Pour SQLite, c'est une seule ligne. On laisse echo=False pour ne pas noyer la console, mais mets-le à True une fois : tu verras le SQL exact que SQLAlchemy génère derrière ton dos.

python
from sqlalchemy import create_engine

# SQLite stocke tout dans un fichier local : tutorial.db
engine = create_engine("sqlite:///tutorial.db", echo=False)

Étape 2 — Décris tes tables avec des classes

Ici, pas de CREATE TABLE à écrire : tu déclares une classe Python par table, et chaque attribut devient une colonne. Le type de chaque colonne est explicite, ce qui te protège des surprises au moment de l'insertion.

python
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
from sqlalchemy import String, Integer, Float


class Base(DeclarativeBase):
    pass


class Article(Base):
    __tablename__ = "articles"

    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    titre: Mapped[str] = mapped_column(String(200))
    mots: Mapped[int] = mapped_column(Integer)
    note: Mapped[float] = mapped_column(Float)

Étape 3 — Crée les tables en une ligne

Base.metadata connaît toutes les classes que tu as déclarées. create_all() génère les tables manquantes. Pour un vrai projet en équipe, tu préféreras Alembic afin de versionner ton schéma, mais pour démarrer, c'est largement suffisant.

python
Base.metadata.create_all(engine)

Étape 4 — Insère des données sans SQL

La session est ton intermédiaire avec la base. Tu y ajoutes des objets Python, et commit() écrit tout en une seule transaction. Le typage t'empêche d'insérer un texte là où la colonne attend un entier.

python
from sqlalchemy.orm import Session


with Session(engine) as session:
    session.add_all([
        Article(titre="SQLAlchemy : le tutoriel", mots=1024, note=4.7),
        Article(titre="Pourquoi j'ai arrêté le SQL brut", mots=810, note=4.2),
        Article(titre="Les bases de données, sans douleur", mots=640, note=3.9),
    ])
    session.commit()

Étape 5 — Interroge avec du Python, pas du SQL

La requête se lit comme du code : tu filtres, tu tries, tu limites. Pas de concaténation de chaînes, donc pas d'injection possible. Le résultat est une liste d'objets Article, avec accès direct aux attributs. La méthode scalars() récupère les lignes sans leur enveloppe.

python
from sqlalchemy import select


with Session(engine) as session:
    resultats = session.execute(
        select(Article)
        .where(Article.mots >= 700)
        .order_by(Article.note.desc())
    ).scalars().all()

    for article in resultats:
        print(f"{article.titre} — note {article.note}")

Étape 6 — Modifie et supprime sans sueur

Modifier un objet, c'est le muter puis committer. Supprimer, c'est une ligne. La session suit tous les changements et ne touche à la base qu'au moment du commit(), ce qui rend les rollbacks naturels en cas de pépin.

python
with Session(engine) as session:
    article = session.get(Article, 1)
    article.note = 5.0  # la mise à jour partira au commit

    vieux = session.get(Article, 3)
    session.delete(vieux)

    session.commit()

Pourquoi ça change tout pour tes projets IA

Dès que ton script manipule des données structurées — les prompts que tu envoies, les réponses des modèles, les scores d'évaluation — le SQL brut devient un boulet. Avec SQLAlchemy, ton code reflète ton domaine : tu manipules des objets Prompt, Reponse, Evaluation, et la base suit derrière. Le même code passe de SQLite en local à PostgreSQL en production en changeant une seule URL de connexion, sans réécrire une requête.

À toi de jouer

Tu tiens les six gestes essentiels : moteur, modèles, création, insertion, requête, mutation. La suite logique, c'est d'ajouter des relations entre tables — un Article appartient à un Auteur via une clé étrangère — puis de brancher Alembic pour versionner ton schéma. Ton script Python vient de gagner un accès à une vraie base de données, sans une seule ligne de SQL à maintenir.