Aller au contenu
Ingestion

Idempotence : rejouer sans doublon

Une tâche idempotente produit le même résultat qu'on la lance une fois ou dix. C'est la condition pour relancer un pipeline après une panne sans créer de doublons ni perdre de lignes.

  • upsert
  • merge
  • on conflict
  • clé naturelle
  • rejeu
  • doublon
  • reprise

Syntaxe

Modèle
-- 1. Upsert sur une clé naturelle (SQLite, PostgreSQL)INSERT INTO cible (cle, col1, col2) VALUES (…)ON CONFLICT (cle) DO UPDATE SET  col1 = excluded.col1,  col2 = excluded.col2;-- 2. MERGE (PostgreSQL, SQL Server, Snowflake, BigQuery, Spark…)MERGE INTO cible cUSING lot l ON c.cle = l.cleWHEN MATCHED THEN UPDATE SET col1 = l.col1WHEN NOT MATCHED THEN INSERT (cle, col1) VALUES (l.cle, l.col1);-- 3. Remplacer la partition traitée, dans une transactionDELETE FROM cible WHERE jour = :jour;INSERT INTO cible SELECT … WHERE jour = :jour;

Exemple

Exemple concret
CREATE TABLE dim_produit (  ref TEXT PRIMARY KEY,   -- clé naturelle venue de la source  libelle TEXT,  prix REAL,  maj_le TEXT);-- Le même lot est chargé deux fois : la tâche a été relancée après-- un délai dépassé, alors que le premier essai avait en fait abouti.INSERT INTO dim_produit (ref, libelle, prix, maj_le) VALUES  ('P01', 'Clavier', 39.9, '2026-10-31'),  ('P02', 'Souris',  19.9, '2026-10-31')ON CONFLICT (ref) DO UPDATE SET  libelle = excluded.libelle,  prix    = excluded.prix,  maj_le  = excluded.maj_leWHERE excluded.maj_le >= dim_produit.maj_le;   -- jamais de retour en arrièreINSERT INTO dim_produit (ref, libelle, prix, maj_le) VALUES  ('P01', 'Clavier', 39.9, '2026-10-31'),  ('P02', 'Souris',  19.9, '2026-10-31')ON CONFLICT (ref) DO UPDATE SET  libelle = excluded.libelle,  prix    = excluded.prix,  maj_le  = excluded.maj_leWHERE excluded.maj_le >= dim_produit.maj_le;SELECT COUNT(*) AS nb_produits FROM dim_produit;-- 2   (et non 4 : le second passage n'a rien ajouté)

À retenir

  1. Le motif « supprimer puis réinsérer la partition du jour » dans une seule transaction est le plus simple pour les tables de faits : relancer le 31 octobre réécrit exactement le 31 octobre.
  2. Dédupliquez sur une clé naturelle ou métier (numéro de commande, référence produit), jamais sur un identifiant auto-incrémenté généré au chargement : il change à chaque essai.
  3. Faites dépendre la tâche de la date logique du lot qu'on lui passe, pas de l'heure courante : relancée trois jours plus tard, elle doit traiter le même jour.
  4. Piège : un simple INSERT suivi d'une relance automatique (retries) double les lignes. Le problème apparaît rarement en test et souvent en production, le jour où le réseau hoquette.
  5. Piège : les effets de bord (envoi d'un e-mail, appel d'API de paiement) ne se rattrapent pas par un upsert. Mémorisez ce qui a déjà été envoyé avec une clé d'idempotence.

Voir aussi