Passer au contenu principal
Une promotion transforme les données analysées et les écrit dans une table cible. Une spécification peut avoir plusieurs promotions (une par dataset de sortie), et chacune exécute une liste ordonnée d’étapes.

Forme de promotion

{
  "dataset_id": "brands",
  "domain": "catalog",
  "conformed_table": "brands",
  "source_table": "marque",
  "source_tables": ["marque"],
  "merge_keys": ["organization_id", "code"],
  "update_columns": ["name", "updated_at"],
  "steps": [ /* étapes de transformation ordonnées */ ]
}
ChampSignification
dataset_idNom du dataset logique.
domainDomaine logique (ex. catalog, sales, inventory).
conformed_tableLa table silver/gold cible.
source_table / source_tablesLa(les) table(s) source que cette promotion lit.
merge_keysColonnes qui identifient une ligne pour l’upsert.
update_columnsLors de l’upsert, quelles colonnes mettre à jour (null/omis = toutes).
stepsLe pipeline ordonné (ci-dessous).

Comportement d’écriture

Les promotions écrivent selon l’un de trois modes — merge (upsert sur merge_keys), append (insérer uniquement), ou overwrite partition (remplacer une partition). En pratique, une promotion avec merge_keys effectue un upsert sur ces clés ; update_columns restreint quelles colonnes sont écrites en cas de correspondance (ex. enrichir uniquement postal_code sans toucher au reste de la ligne).

Ordonnancement

Les étapes s’exécutent de haut en bas. Chaque étape voit la sortie de la précédente, donc l’ordre importe — ex. ajouter/renommer les colonnes avant generate_id, et exécuter une id_mapping_output uniquement après l’existence de l’id.

Catalogue d’étapes

Chaque étape est un objet avec un type. Ci-dessous, groupées par objectif.

Mise en forme

{ "type": "coerce_types", "columns": { "quantity": "INT", "price": "DOUBLE", "date": "TIMESTAMP" } }
Convertit chaque colonne listée au type Spark SQL donné.
{ "type": "filter", "condition": "quantity > 0 AND date IS NOT NULL" }
condition est une expression SQL WHERE (sans le mot-clé WHERE).
{ "type": "deduplicate", "columns": ["no_ligmvt"], "strategy": "keep_last", "order_by": ["updated_at"], "order_desc": true }
strategy : drop (par défaut), keep_first, ou keep_last. order_by / order_desc décident quelle ligne survit pour keep_first/keep_last.
{ "type": "add_column", "column": "created_at", "expression": "current_timestamp()" }
expression est toute expression scalaire SQL (littéraux, fonctions, CASE, références à d’autres colonnes).
{ "type": "rename_columns", "columns": { "no_marque": "code", "nom": "name" } }
Mappe les noms source → cible.
{ "type": "select_columns", "columns": ["id", "code", "name"] }
Supprime tout ce qui n’est pas listé.
{ "type": "drop_columns", "columns": ["_tmp", "_extra"] }
{ "type": "inject_value", "column": "organization_id", "value_key": "organization_id" }
Écrit une valeur du contexte d’exécution (ex. organization_id, created_by) comme colonne littérale.

Jointure

{
  "type": "join",
  "target_dataset": "shops",
  "source_column": "shop_code",
  "target_column": "code",
  "join_type": "left",
  "select_columns": [ { "source": "id", "alias": "shop_id" }, { "source": "name" } ],
  "columns_to_drop": ["_tmp"],
  "deduplicate_on": ["code"]
}
join_type : left (par défaut), inner, outer, right. select_columns choisit (et optionnellement ajoute un alias à) les colonnes du dataset joint.
{
  "type": "sequential_join",
  "target_dataset": "libtaille",
  "join_column": "no_libtaille",
  "target_join_column": null,
  "fallback_join_column": null,
  "select_columns": [],
  "select_expressions": { "_size_label": "libelle" },
  "deduplicate_on": ["no_libtaille"],
  "join_type": "left"
}
Ajoute deux capacités par rapport à join : une fallback_join_column (clé secondaire de style COALESCE) et select_expressions (expressions SQL personnalisées sélectionnées de la cible).
{
  "type": "aggregation_join",
  "target_dataset": "detcde",
  "group_by_columns": ["no_ligcde"],
  "aggregate_columns": [
    { "source_column": "pa", "function": "avg", "alias": "_detcde_pa", "cast_type": "double" }
  ],
  "join_column": "no_ligcde",
  "join_type": "left",
  "order_by": null,
  "order_desc": false
}
Agrège la cible avec functionavg, max, min, sum, count, first, puis joint le résultat sur join_column.

Remodèlement

{
  "type": "unpivot",
  "id_columns": ["product_id"],
  "value_columns": ["jan", "feb", "mar"],
  "variable_column": "month",
  "value_column": "value"
}
Transforme { id, col1, col2, … } en lignes { id, variable, value }. variable_column/value_column sont par défaut variable/value.

Identité et taxonomie

{ "type": "generate_id", "output_column": "id", "key_columns": ["code"], "namespace": null }
Dérive un id déterministe à partir de key_columns — les mêmes valeurs de clés produisent le même id entre les exécutions (idempotent), ce qui rend la ré-ingestion sûre. Un namespace optionnel cadre la dérivation (UUID v5). Par défaut : output_column = id, key_columns = toutes les colonnes non nulles.
{ "type": "id_mapping_output", "mapping_type": "brands", "code_column": "code", "id_column": "id", "extra_columns": [] }
Persiste un mapping de code_column → id_column sous mapping_type, pour que les promotions ultérieures (dans cette spécification ou une autre) puissent résoudre les clés étrangères par rapport à lui.
{ "type": "id_mapping_join", "mapping_type": "brands", "source_column": "brand_code", "output_column": "brand_id", "extra_output_columns": ["shop_id"], "deduplicate": true }
Cherche source_column dans le mapping créé par une id_mapping_output antérieure et écrit l’id résolu dans output_column.
{ "type": "taxonomy_mapping", "taxonomy_type": "size", "source_column": "_size_label", "source_id_column": "no_libtaille", "output_column": "taxonomy_id" }
Résout un label textuel (ex. une taille ou une couleur) en id de taxonomie Solya. source_id_column fournit optionnellement la référence POS pour la désambiguïsation.

Référence des sous-options

ÉnumérationValeurs
Stratégie de déduplicationdrop, keep_first, keep_last
Type de jointureleft, inner, outer, right
Fonction d’agrégationavg, max, min, sum, count, first
Mode d’écrituremerge, append, overwrite_partition
Les clés étrangères inter-spécifications fonctionnent via la paire id_mapping_outputid_mapping_join : une promotion publie le mapping, les promotions ultérieures le consomment. Voir les exemples travaillés.