Brains Up AnalyticsBRAINSUPAnalytics
Azure Data FactoryChargement IncrémentalWatermarkETL

Chargement incrémental dans Azure Data Factory : le pattern de watermark pas à pas

Comment faire un chargement incrémental dans Azure Data Factory avec le pattern de watermark : Lookup de la dernière valeur, Copy Data uniquement de la nouvelle fenêtre et Stored Procedure qui met à jour le contrôle. Guide pratique.

Il y a un pattern qui se répète dans presque tout pipeline d'ingestion : au début du projet, recharger la table entière à chaque exécution semble inoffensif. La source est petite, le chargement tourne en quelques secondes, et personne n'y réfléchit à deux fois. Le problème apparaît des mois plus tard, quand la table compte des dizaines de millions de lignes et que le chargement « full » qui tournait la nuit se met à empiéter sur les heures de bureau.

La solution dans Azure Data Factory n'exige ni nouvel outil ni de réécrire le pipeline de zéro. C'est le pattern de watermark : au lieu de tout retraiter, vous gardez la dernière valeur déjà chargée et, à l'exécution suivante, vous n'apportez que les lignes arrivées après elle.

Ce qu'est un watermark

Un watermark, c'est simplement le point jusqu'où vous avez déjà chargé. En pratique, c'est la valeur maximale d'une colonne qui ne fait que croître à la source :

  • une colonne de date/heure de modification (ModifiedDate, UpdatedAt) ;
  • un identifiant incrémental (Id, RowVersion) ;
  • ou un marqueur de change tracking / CDC, quand la source n'a pas de colonne fiable.

Vous conservez cette valeur dans une petite table de contrôle. À chaque exécution, le pipeline lit l'ancien watermark, découvre le nouveau maximum à la source et ne déplace que l'intervalle entre les deux.

La table de contrôle

Commencez par quelque chose de minimal :

CREATE TABLE dbo.controle_chargement (
    TableCible      sysname      NOT NULL,
    WatermarkValue  datetime2    NOT NULL,
    CONSTRAINT PK_controle_chargement PRIMARY KEY (TableCible)
);

-- amorce : une date très ancienne pour que le premier chargement prenne tout
INSERT INTO dbo.controle_chargement VALUES ('ventes', '1900-01-01');

Étape 1 — Lookup de l'ancien et du nouveau watermark

Dans le pipeline, utilisez deux activités Lookup :

  • Lookup « ancien watermark » — lit la valeur actuelle de la table de contrôle :
SELECT WatermarkValue AS old
FROM dbo.controle_chargement
WHERE TableCible = 'ventes';
  • Lookup « nouveau watermark » — lit le maximum actuel de la source :
SELECT MAX(ModifiedDate) AS new
FROM dbo.ventes;

Lire le nouveau maximum une fois, au début, ferme la fenêtre (old, new] avant de déplacer la moindre donnée. Cela évite le problème classique des lignes qui arrivent pendant le chargement et resteraient dans les limbes entre une exécution et la suivante.

Étape 2 — Copy Data uniquement de la nouvelle fenêtre

Dans l'activité Copy Data, utilisez une requête dynamique sur la source, paramétrée avec la sortie des deux Lookups :

SELECT *
FROM dbo.ventes
WHERE ModifiedDate >  '@{activity('lkp_old').output.firstRow.old}'
  AND ModifiedDate <= '@{activity('lkp_new').output.firstRow.new}'

Le détail qui évite la duplication : utilisez strictement supérieur à l'ancien watermark et inférieur ou égal au nouveau (> @old AND <= @new). Si vous utilisez >= des deux côtés, la ligne exactement à la frontière entre dans deux exécutions consécutives.

Étape 3 — Une Stored Procedure met à jour le watermark

La dernière activité du pipeline est une Stored Procedure qui écrit la nouvelle valeur seulement après que le Copy s'est terminé avec succès :

CREATE PROCEDURE dbo.sp_maj_watermark
    @Table sysname,
    @NouvelleValeur datetime2
AS
BEGIN
    UPDATE dbo.controle_chargement
    SET WatermarkValue = @NouvelleValeur
    WHERE TableCible = @Table;
END

Comme la mise à jour dépend du succès du Copy, si le pipeline échoue en cours de route le watermark n'avance pas — et la réexécution refait simplement la même fenêtre. C'est ce qui rend le chargement idempotent : le relancer ne duplique ni ne saute aucune ligne.

Quand le watermark ne suffit pas

Le pattern suppose une colonne qui ne fait que croître et reflète toute modification. Il marche très bien pour les inserts et updates avec un ModifiedDate maintenu par l'application, mais il a des limites :

  • Les deletes physiques n'apparaissent pas — la ligne disparaît de la source sans toucher au maximum. Pour les capturer, utilisez un soft delete (un flag) ou le CDC.
  • Sources sans colonne de modification fiable — remplacez le watermark par le Change Tracking ou le CDC de SQL Server, qui livrent exactement l'ensemble des modifications depuis le dernier point.
  • Fabric / OneLake — le même pattern vaut dans le Copy Job et les pipelines Fabric Data Factory ; l'interface change, pas la logique.

Checklist rapide

  1. Table de contrôle avec un watermark par cible, amorcée avec une valeur ancienne.
  2. Lookup de l'ancien watermark (contrôle) + Lookup du nouveau maximum (source).
  3. Copy Data avec la requête WHERE colonne > @old AND colonne <= @new.
  4. Stored Procedure écrit @new dans le contrôle après le succès du Copy.
  5. Pour les deletes ou les sources sans colonne de date, migrer vers le CDC / change tracking.

Conclusion

Avant de demander plus de compute ou de comprimer la fenêtre nocturne, remplacez le chargement full par un incrémental. Le pattern de watermark dans Azure Data Factory est l'un des réglages au meilleur rapport coût-bénéfice en ingestion : moins de données qui circulent, des chargements en minutes, et la liberté de tourner toutes les heures au lieu d'une fois par jour. C'est du contrôle d'état, pas de la magie — et cela tient en quatre activités dans le pipeline.

Articles liés

Vous avez aimé ? Découvrez les e-books pour du contenu approfondi.

E-books