tva
← Analyses

Créer un entrepôt de données Amazon avec FastAPI et TimescaleDB

La SP-API d’Amazon donne accès à un volume substantiel de données opérationnelles — commandes, stocks, règlements, performances du catalogue — et l’API distincte Amazon Ads API fournit les données publicitaires. Mais en réalité, les données ne sont utiles que si vous pouvez les interroger. Les rapports natifs d’Amazon sont éphémères, soumis à des limites de débit, et ne sont pas conçus pour les questions opérationnelles qui comptent le plus pour un vendeur gérant une activité sur plusieurs places de marché. Vous pouvez voir ce qui s’est passé. Vous ne pouvez pas facilement demander ce qui se passe sur toutes les places de marché simultanément, ni quelle était la tendance de la demande au cours des quatre-vingt-dix derniers jours pour un ASIN spécifique dans une région logistique donnée.

Ce billet décrit l’architecture que nous utilisons pour un entrepôt de données Amazon : FastAPI comme couche API, TimescaleDB comme base de stockage de séries temporelles, et Celery pour le pipeline asynchrone de rapports SP-API. L’objectif est un système où les données que nous récupérons via les API d’Amazon sont stockées sous une forme interrogeable que vous contrôlez, avec suffisamment de structure pour alimenter les prévisions de demande et l’analyse de données opérationnelles sans nécessiter une équipe d’ingénierie des données pour le maintenir.

Pourquoi les outils natifs d’Amazon sont insuffisants

Les rapports Seller Central couvrent la plupart des besoins opérationnels pour une seule place de marché avec un petit catalogue. Les lacunes deviennent apparentes à grande échelle. Les rapports sont générés à la demande et expirent. Il n’y a pas de couche de requêtes persistante — vous lancez un rapport, téléchargez un fichier, et les données se trouvent uniquement dans ce fichier. Exécuter le même rapport dans six mois donnera les données de cette date, et non celles d’aujourd’hui.

Cela signifie que toute analyse historique nécessite soit que quelqu’un ait téléchargé et stocké chaque rapport pertinent au bon intervalle, soit que vous reconstituiez l’historique à partir d’exports détaillés par transaction — qui sont eux-mêmes soumis à des limites de débit, paginés sur des fenêtres limitées, et structurés pour la récupération d’enregistrements individuels plutôt que pour l’analyse en masse.

Le tableau de bord Business Reports d’Amazon fournit des données de tendances agrégées, mais la granularité et la durée de conservation sont fixées par les décisions produit d’Amazon, non par vos besoins analytiques. La console publicitaire a son propre modèle de données qui s’articule mal avec les données d’exécution des commandes. Les données de règlement arrivent sur un cycle de deux semaines et nécessitent une analyse syntaxique complexe pour être rapprochées des données de commandes.

Un entrepôt personnalisé résout simultanément les problèmes de conservation et d’accès aux données par requête. Vous possédez le stockage, vous définissez la durée de conservation, et vous écrivez les requêtes qui répondent aux questions que votre entreprise se pose réellement — pas les questions pour lesquelles les tableaux de bord d’Amazon ont été conçus.

Choix technologiques

Nous avons choisi TimescaleDB comme base principale parce que la plupart des données opérationnelles Amazon sont intrinsèquement des séries temporelles. Les commandes ont des horodatages. Les instantanés de stock décrivent une situation à un moment donné. Les périodes de règlement ont des dates de début et de fin. Les dépenses et impressions publicitaires s’accumulent dans le temps. TimescaleDB est PostgreSQL avec des extensions hypertable qui rendent les requêtes sur des plages temporelles de grands ensembles de données nettement plus efficaces que le PostgreSQL standard, tout en maintenant une compatibilité SQL complète. Il n’y a pas de nouveau langage de requête à apprendre et aucun modèle d’exploitation sensiblement différent de celui d’une installation Postgres standard.

FastAPI fournit la couche API entre les workers Celery qui extraient les données de la SP-API et les consommateurs internes qui interrogent l’entrepôt. Il gère l’authentification, la validation des requêtes et la sérialisation des réponses avec un minimum de code répétitif. Pour un service interne non exposé à l’internet public, la documentation OpenAPI automatique de FastAPI est particulièrement utile : elle fournit une définition d’interface interrogeable qui facilite l’écriture de nouveaux consommateurs sans devoir reconstituer le modèle de données à partir du schéma de la base.

Celery gère le pipeline asynchrone de rapports SP-API. La génération de rapports SP-API est asynchrone par conception — vous demandez un rapport, interrogez périodiquement son statut, téléchargez le résultat quand il est prêt, et traitez le fichier. Cela correspond naturellement à une chaîne de tâches Celery : une tâche pour initier la demande de rapport, une tâche périodique pour interroger le statut du rapport, une tâche pour télécharger et stocker le fichier brut, et une tâche pour analyser et charger les données structurées dans TimescaleDB. Redis sert d’intermédiaire de messagerie pour Celery et de backend de stockage des résultats.

Modèle de données

Les tables principales reflètent les domaines de données principaux de la SP-API. Le principe de conception est que chaque table doit répondre à une classe spécifique de questions opérationnelles sans nécessiter de jointures entre plusieurs types de rapports.

Commandes est une hypertable partitionnée sur purchase_date. Chaque ligne représente un article de commande individuel plutôt qu’une commande entière, car l’analyse au niveau article — par ASIN, canal d’exécution des commandes, place de marché — est la granularité analytique la plus courante. Les agrégats au niveau commande sont dérivés des enregistrements au niveau article. L’intervalle de partition de l’hypertable est réglé sur une semaine, ce qui offre de bonnes performances pour les requêtes sur des fenêtres glissantes utilisées dans les prévisions de demande.

Instantanés de stock stocke la sortie des rapports de stock au moment de leur extraction. Le stock FBA n’est pas un flux d’événements — c’est un état qui change en permanence et n’est pas entièrement reconstituable à partir des enregistrements de commandes seuls (les retours, ajustements et transferts affectent le stock sans commandes correspondantes). Nous extrayons des instantanés de stock deux fois par jour et les stockons sous forme d’enregistrements décrivant un instant précis. La fonctionnalité d’agrégats continus de TimescaleDB calcule des moyennes quotidiennes et hebdomadaires glissantes à partir de ces instantanés sans que la requête ait à parcourir l’historique complet des instantanés.

Règlements stocke les rapports de règlement après analyse, chaque poste correspondant à une ligne de la table. Le modèle de données des règlements est l’un des défis d’analyse syntaxique les plus complexes dans l’écosystème SP-API — Amazon utilise des codes de type de transaction différents selon les places de marché, et les lignes de frais utilisent des conventions de nommage qui ne sont pas entièrement cohérentes entre les régions. Nous maintenons une table de correspondance qui normalise les noms des types de frais entre les marchés selon une taxonomie interne cohérente.

Catalogue stocke un instantané du catalogue de produits — ASIN, titres, catégories, relations entre variantes — mis à jour hebdomadairement. Cette table est principalement une table de référence pour les autres tables et n’utilise pas de structure hypertable, car les données n’ont pas de caractéristiques temporelles significatives.

TimescaleDB en pratique

Les hypertables sont la fonctionnalité centrale de TimescaleDB. Créer une hypertable à partir d’une table PostgreSQL standard nécessite une seule commande spécifiant la colonne temporelle et l’intervalle de partition. Ensuite, les requêtes SQL standard fonctionnent sans modification, et le planificateur de requêtes de TimescaleDB applique automatiquement l’exclusion des partitions, ou chunks — en ignorant celles qui se trouvent hors de la plage temporelle de la requête — pour rendre les requêtes bornées dans le temps rapides même sur de grands ensembles de données.

Les agrégats continus sont la deuxième fonctionnalité que nous utilisons intensivement. Un agrégat continu est une vue matérialisée que TimescaleDB met à jour de manière incrémentielle au fur et à mesure que de nouvelles données arrivent dans l’hypertable. Pour les prévisions de demande, nous maintenons un agrégat continu quotidien des ventes par ASIN et place de marché, à partir duquel sont calculés les totaux de ventes glissants sur 7, 30 et 90 jours. Cet agrégat est mis à jour automatiquement selon un calendrier défini, et les requêtes qui l’interrogent portent sur des données précalculées plutôt que sur l’hypertable complète, ce qui rend l’analyse de données dans les tableaux de bord suffisamment rapide pour un usage interactif.

CREATE MATERIALIZED VIEW daily_sales_by_asin
WITH (timescaledb.continuous) AS
SELECT
  time_bucket('1 day', purchase_date) AS day,
  asin,
  marketplace_id,
  SUM(quantity_ordered) AS units_sold,
  SUM(item_price_amount) AS revenue
FROM order_items
GROUP BY day, asin, marketplace_id;

Cette vue est rafraîchie automatiquement par la politique en arrière-plan de TimescaleDB, que nous configurons pour s’exécuter toutes les heures. Les sommes glissantes sur 90 jours utilisées dans les prévisions sont calculées comme des requêtes utilisant des fonctions de fenêtre sur cette vue matérialisée, et non sur la table des données brutes des articles de commande.

Le pipeline Celery

Le pipeline de rapports SP-API s’exécute comme un ensemble de tâches Celery selon un calendrier géré par Celery Beat. Chaque type de rapport a son propre calendrier : les commandes sont extraites toutes les heures, les stocks deux fois par jour, les règlements sur un cycle de deux semaines qui reflète les périodes de règlement Amazon.

Le pipeline pour chaque type de rapport suit la même structure : une tâche planifiée initie une demande de rapport via la SP-API, en stockant l’identifiant de demande dans Redis. Une tâche d’interrogation périodique s’exécute à quelques minutes d’intervalle, vérifie le statut du rapport via la SP-API, et quand le rapport est prêt, met en file d’attente une tâche de téléchargement. La tâche de téléchargement récupère le document du rapport, stocke le fichier brut sur disque, et met en file d’attente une tâche de traitement. La tâche de traitement analyse le fichier et charge les enregistrements structurés dans TimescaleDB.

La déduplication est gérée à l’étape de traitement plutôt qu’au niveau de la base de données. La SP-API retourne occasionnellement des enregistrements dupliqués dans des rapports dont les périodes se chevauchent. Nous maintenons une empreinte des champs d’identification de chaque enregistrement et vérifions les enregistrements existants avant l’insertion, ce qui évite l’accumulation de lignes dupliquées dans l’entrepôt au fil du temps, à condition que chaque type de rapport soit traité séquentiellement ; un traitement concurrent nécessiterait également une contrainte d’unicité dans la base de données.

La gestion des erreurs suit une politique simple : les erreurs SP-API transitoires (réponses signalant une limite de débit atteinte, indisponibilité temporaire du service) déclenchent une nouvelle tentative Celery avec temporisation exponentielle. Les erreurs persistantes — documents de rapport malformés, changements de schéma inattendus, échecs d’analyse syntaxique — sont consignées avec le contexte complet et arrêtent le traitement pour ce type de rapport sans affecter les autres pipelines. Nous examinons le journal d’erreurs lors de la revue opérationnelle hebdomadaire plutôt que de traiter ces situations comme des incidents urgents, sauf si elles affectent les données de rapprochement des règlements.

La base des prévisions de demande

L’entrepôt de données n’implémente pas directement les prévisions de demande. Il fournit les données nécessaires pour établir des prévisions : des séries temporelles de ventes fiables, détaillées par ASIN, place de marché et jour, avec suffisamment d’historique pour identifier les tendances saisonnières et calculer des estimations de tendance statistiquement significatives.

L’agrégat continu quotidien décrit ci-dessus alimente les signaux de demande glissants sur 7, 30 et 90 jours. Ces signaux alimentent des modèles de prévision simples — moyennes mobiles pondérées et extrapolation de tendance linéaire pour les produits stables, avec des facteurs d’ajustement manuels pour les produits à saisonnalité connue. Les modèles s’exécutent comme des points de terminaison FastAPI qui interrogent les agrégats continus et retournent des estimations ponctuelles avec des intervalles de confiance.

Des approches de prévision plus sophistiquées deviennent réalisables une fois ces données disponibles. Nous avons expérimenté le lissage exponentiel Holt-Winters pour les produits avec des cycles saisonniers marqués, et la régression simple sur des signaux externes (dépenses publicitaires, changements de prix) pour les produits où ces variables sont des moteurs de demande significatifs. Mais en réalité, l’amélioration de la précision des prévisions de ces approches plus complexes par rapport aux moyennes mobiles pondérées bien calibrées est modeste pour la plupart des produits — la qualité et la longueur de l’historique des données comptent plus que la complexité du modèle.

Ce que cela rend possible

Les possibilités concrètes qu’ouvre l’entrepôt méritent d’être détaillées : elles changent la nature des opérations réalisables, au-delà d’une simple amélioration progressive de la vitesse de production des rapports.

La planification des stocks entre places de marché devient réalisable. Avec des données de rythme des ventes par ASIN et place de marché et le stock FBA actuel issu de la table d’instantanés, nous pouvons calculer le nombre de jours de couverture du stock pour chaque référence produit (SKU) sur chaque place de marché et générer automatiquement des recommandations de réapprovisionnement plutôt que de passer par une revue manuelle marché par marché.

Le rapprochement des règlements devient auditable. Avec les données de commandes et de règlements stockées dans le même système, il devient possible de vérifier que chaque article commandé a été réglé au taux prévu — et ainsi repérer les écarts de frais, les remboursements incorrects ou les erreurs de règlement qui ne sont autrement visibles que pour les vendeurs qui rapprochent manuellement les lignes. Cette vérification s’exécute comme un rapport hebdomadaire sur l’entrepôt plutôt que de nécessiter un travail manuel.

L’analyse publicitaire devient possible au niveau ASIN. En joignant les données publicitaires aux données de commandes sur des identifiants partagés, nous pouvons suivre l’évolution conjointe des dépenses publicitaires et des ventes organiques dans le temps — une question à laquelle la console publicitaire d’Amazon ne répond pas directement, car elle montre les ventes attribuées à la publicité mais pas les ventes organiques qui les entourent. Les données jointes montrent une corrélation ; attribuer les changements de classement organique à la publicité nécessiterait en plus des données de classement et une comparaison contrôlée.


Analyses connexes

Pour aller plus loin