> ## Content Index
> Fetch the complete content index at: https://www.idriss-benbassou.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Atelier AWS : modéliser la couche gold d'un data lake (sans guide)
- URL: https://www.idriss-benbassou.com/atelier-aws-pipeline-complet-table-curated-data-lake/
- Published: 2026-08-27T19:30:20.000Z
- Updated: 2026-08-27T19:30:20.000Z
- Author: Idriss BENBASSOU
- Tags: AWS, #rating-3

Depuis le début de [la formation](https://www.idriss-benbassou.com/formation-aws/), chaque manip était détaillée et guidée. C'est bien pour apprendre, mais ce n'est pas comme ça que ça se passe en mission car généralement on va te donner le besoin métier et tu te débrouilles.

Alors on inverse. Cet article, c'est un sujet, pas un tutoriel, et c'est sans correction.

Et ce n'est pas un exercice pour l'exercice, les tables que tu vas construire sont celles qui alimenteront les dashboards du prochain article.

## Le sujet

> **Préparer les données pour le dashboard des ventes**  
>  
> Le métier veut un dashboard avec le chiffre d'affaires par catégorie de produit, le top 10 des clients, la répartition des ventes par ville, et il aimerait aussi repérer ses meilleurs clients et suivre les nouveaux acheteurs mois par mois.  
>  
> Livrable attendu : un modèle prêt à brancher sur l'outil de BI.

C'est tout.

## Le livrable attendu

On attend un schéma en étoile, une table de faits entourée de ses dimensions et donc :

- [Un job Glue](https://www.idriss-benbassou.com/glue-etl-studio-job-nettoyage-raw-clean/) qui construit les quatre tables en full donc rejouable sans doubler les lignes
- [Un rôle IAM](https://www.idriss-benbassou.com/iam-data-roles-policies-moindre-privilege/) propre par service, avec des policies limitées à ton bucket et donc aucun `*FullAccess` ou une règle global
- [Un chargement des données dans Redshift](https://www.idriss-benbassou.com/aws-redshift-serverless-copy-s3-athena-vs-redshift/)
- [Une step function ](https://www.idriss-benbassou.com/aws-step-functions-eventbridge-orchestrer-pipeline-data/)qui enchaîne crawler, job clean avec attente réelle du crawler et retry comme on a vu dans [la formation](https://www.idriss-benbassou.com/aws-step-functions-eventbridge-orchestrer-pipeline-data/) et à la fin injecter les données dans Redshift
- Un déclenchement automatique, planifié avec [EventBridge ](https://www.idriss-benbassou.com/aws-step-functions-eventbridge-orchestrer-pipeline-data/)ou sur arrivée de fichier avec [Lambda](https://www.idriss-benbassou.com/aws-lambda-trigger-s3-python-validation-fichier/).
- Les tables :

### fact\_ventes : la table de faits

Une ligne par commande, avec les clés étrangères vers les dims. Pas de libellés dedans, ni nom de client, ni catégorie produit, juste les clés.

Les colonnes attendues :

- `commande_id`, `client_id`, `produit_id`.
- `date_key` la date au format entier `20260315`.
- `quantite` et `montant`, le montant réellement facturé sur la commande.
- `montant_theorique` ce que la commande aurait dû coûter au prix catalogue, donc `quantite × prix_unitaire` du produit. Tu devras joindre les produits pour l'obtenir.
- `remise ` l'écart en euros entre le théorique et le réel. Une valeur positive veut dire que le client a payé moins que le prix catalogue.
- `taux_remise` la même chose en pourcentage du montant théorique, arrondi à 2 décimales. C'est pour repérer les produits systématiquement bradés.
- `rang_commande_client` le numéro de la commande dans l'historique du client, trié par date. La toute première commande d'un client porte le rang 1, la suivante 2, et ainsi de suite..... (indice : il faut utiliser [les windows function](https://www.idriss-benbassou.com/snowflake-sql-window-functions-over-partition-by-order-by-rows/))
- `is_premiere_commande` un booléen vrai quand le rang vaut 1 et c'est pour compter les nouveaux acheteurs facilement par mois, sans recalculer quoi que ce soit dans le dashboard.
- Il faut exclure les commandes annulées donc `statut` != 'annulee'
- `mois` en dernier la colonne de partition.

Format Parquet, compression Snappy, partitionnée par mois.

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/08/image-132.png)

### dim\_client, la dimension client

Une ligne par client**.**

- `client_id`, `prenom`, `nom`, `ville`, `code_postal`.
- `nom_complet`, la concaténation propre du prénom et du nom.

Nb : un client du référentiel peut n'avoir jamais commandé. Il doit quand même apparaître dans la dimension.

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/08/image-133.png)

### dim\_produit, la dimension produit

Même logique, une ligne par produit.

- `produit_id`, `nom_produit`, `categorie`, `prix_unitaire`.
- `gamme`, un attribut dérivé du `prix_unitaire` : **Premium** au-dessus de 100 €, **Standard** entre 30 et 100 €, **Entrée de gamme** en dessous.

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/08/image-134.png)

### dim\_date, la dimension calendrier

Une ligne par jour couvert par les ventes.

- `date_key` (l'entier `20260315`), `date_complete`.
- `annee`, `mois`, `jour`, `trimestre`.
- `nom_mois` en français, `nom_jour` en français.
- `numero_semaine`.

Bonus un peu challengeant, car on ne l’a pas vu dans la formation, mais c’est un skill purement SQL à avoir. Si une CTE récursive ne te parle pas du tout, je t'invite à t'entraîner dans [le lab sql de datacertification.fr](https://datacertification.fr/sql?ref=idriss-benbassou.com)

![](https://storage.ghost.io/c/60/f1/60f18be4-df79-4956-8e4a-c2fa80212e93/content/images/2026/08/image-135.png)

### Les volumes attendus

Il faut trouver : 949 lignes dans `fact_ventes`, 200 dans `dim_client`, 32 dans `dim_produit`, et environ 179 dans `dim_date`. Si ta table de faits est à 995, tu as oublié d'exclure les annulées. Au-dessus de 1 000, tu as un problème de jointure ou de doublons

## Bonus, le JSON imbriqué

Si tu veux aller plus loin, il reste un fichier auquel on n'a pas touché depuis le module collecte, `evenements_web.json`. Il contient 300 événements de tracking, avec une structure imbriquée, un objet `client` et un objet `page` dans chaque événement.

L'objectif c'est de compter les visites par type d'événement et par device, et savoir combien de clients ayant commandé sont aussi passés par le site.

Pour info, Athena sait lire les structures imbriquées avec la notation pointée (`client.device`) et déplier les tableaux avec `UNNEST`, et le crawler sait détecter la structure du JSON tout seul.

## À toi de jouer

Prends le temps, compte une bonne heure ou deux si tu fais tout.

Si tu bloques ou si tu veux un indice, écris-moi à idriss.benbassou@ib-data.fr.

## 

## La suite ?

Prochain article, on branche QuickSight dessus, on relie les dimensions à la table de faits, et on construit les visuels demandés par le métier. Le pipeline sera enfin complet, du fichier CSV brut à l'écran que le métier consulte.

## Aller plus loin

Le programme complet du parcours est sur la page de [la formation AWS](https://www.idriss-benbassou.com/formation-aws/).

Tu prépares la certification AWS Certified Data Engineer Associate (DEA-C01) ? Ce type d'exercice couvre plusieurs domaines de l'examen à la fois, catalogue, transformation et formats. Pour t'entraîner, j'ai créé des questions d'examen blanc en français.

👉 [S'entraîner sur DataCertification.fr](https://datacertification.fr/certifications?ref=idriss-benbassou.com)

Tu veux que je t'accompagne sur ton projet data (AWS, Snowflake, dbt, modélisation, coûts) ?

👉 [Réserver un appel de 30 minutes](https://calendly.com/idriss-benbassou-datavio/30min?ref=idriss-benbassou.com)