Débutant12 min de lecture

Comment exporter une table DynamoDB en CSV (4 méthodes)

DynamoDB n'a pas de bouton natif « exporter en CSV ». Chaque valeur revient enveloppée dans le JSON marshallé de DynamoDB{"S": "..."}, {"N": "123"}, {"M": {...}} — et une table peut contenir des maps, des listes et des sets imbriqués sans représentation évidente en colonnes plates. Donc « exporter DynamoDB en CSV » est en réalité deux problèmes : sortir les items, puis aplatir le JSON typé en lignes. Ni la console ni l'export managé ne font la seconde étape pour toi.

Ce guide classe quatre approches selon la taille de la table et la quantité d'imbrication que portent tes items.

Comment exporter une table DynamoDB en CSV ?

DynamoDB ne propose pas d'export CSV natif : tu scannes ou prends un snapshot de la table, puis tu aplatis son JSON typé en lignes. Pour une petite table, utilise AWS CLI scan + jq ou un court script ; pour les grandes tables, exporte vers S3 puis convertis ; pour un CSV filtré et prêt à l'emploi, utilise une interface graphique comme DynoTable.

  • Petite table, ponctuel : AWS CLI scan + jq, ou un script de 20 lignes (Méthode 1 / Méthode 3). Convient jusqu'à ce que des attributs imbriqués apparaissent.
  • Grande table (Go+) : export DynamoDB vers S3 (Méthode 2), puis convertis le dump. Il s'exécute de façon asynchrone et ne consomme aucune capacité de lecture — mais il produit du JSON DynamoDB, pas du CSV.
  • CSV filtré / mis en forme (un sous-ensemble de colonnes, seulement certains items) : un export GUI ou un script. L'export S3 managé te donne la table entière, sans filtre.

Méthode 1 : scan AWS CLI + jq

Pour une petite table, tu peux la scanner et remodeler la sortie avec jq. Un Scan lit chaque item de la table et le renvoie par pages allant jusqu'à 1 Mo ; la CLI suit la pagination pour toi automatiquement (docs AWS : Scanner les tables).

aws dynamodb scan --table-name MyTable --output json \
  | jq -r '.Items[] | [.id.S, .name.S, .price.N] | @csv' \
  > out.csv

Le piège est dans cette ligne jq : tu dois écrire à la main .id.S, .name.S, .price.N — en passant outre le descripteur de type de chaque attribut (S, N, B, BOOL, M, L, SS, NS, BS) pour obtenir la valeur brute. C'est gérable pour une table plate à trois colonnes de chaînes. Cela s'effondre dès que tu as :

  • Des maps/listes imbriquées{"M": {...}} ou {"L": [...]} n'ont pas de colonne unique où s'aplatir ; @csv s'étrangle, ou tu encodes la cellule en JSON à la main.
  • Des sets{"SS": ["a","b"]} est un tableau, pas un scalaire.
  • Des attributs creux — DynamoDB est sans schéma, donc l'item A peut avoir un price et l'item B non. Ta liste de colonnes fixe supprime ou décale silencieusement des colonnes.

Il n'y a pas non plus de --output csv qui comprenne les types DynamoDB. La sortie csv de la CLI aplatit la réponse brute, descripteurs compris — donc tu as toujours besoin de jq (ou d'un script) pour retirer les tags de type. C'est la raison centrale pour laquelle « exporter une table DynamoDB en CSV via AWS CLI » n'est jamais une affaire d'une seule ligne au-delà du cas trivial.

Pour exporter ainsi une table plus grande sans y passer la journée, parallélise le scan avec --segment / --total-segments (docs AWS : Scan parallèle — DynamoDB « assigne les items à des segments en appliquant une fonction de hachage à la clé de partition de chaque item », donc les segments peuvent être inégaux), et lis la pagination pour ne pas t'arrêter à la première page de 1 Mo.

Méthode 2 : export DynamoDB vers S3 (grandes tables)

Pour les tables d'une taille réelle, l'export managé vers Amazon S3 est le bon outil. Il exporte un instantané depuis n'importe quel point de ta fenêtre de point-in-time recovery (PITR) — donc le PITR doit être activé sur la table au préalable — s'exécute de façon asynchrone, et ne consomme aucune unité de capacité de lecture, donc il n'a aucun impact sur le débit ou la disponibilité de ta table (docs AWS : « Les exports sont asynchrones, ils ne consomment pas d'unités de capacité de lecture (RCU) et n'ont aucun impact sur la performance et la disponibilité de la table » ; « Tu dois activer le PITR sur ta table pour utiliser la fonctionnalité d'export »). C'est aussi ce que déclenche l'action Exports vers S3 de la console en coulisses : la console n'est qu'un front-end pour la même API, elle porte donc le même prérequis PITR et la même sortie JSON.

aws dynamodb export-table-to-point-in-time \
  --table-arn arn:aws:dynamodb:us-east-1:123456789012:table/MyTable \
  --s3-bucket my-export-bucket \
  --export-format DYNAMODB_JSON

Le seul écueil : l'export S3 ne produit pas de CSV. Il écrit du JSON DynamoDB ou de l'Amazon Ion uniquement, sous forme de fichiers gzippés au format JSON-lines (un item par ligne), plus des fichiers de manifeste (docs AWS : format de sortie d'export — les fichiers de données sont écrits en .json.gz, « le format est JSON lines », aux côtés de manifest-summary.json / manifest-files.json). Tu as toujours besoin d'une étape de conversion ensuite :

  • Athena / Glue lisent directement le JSON DynamoDB exporté — pointe une table sur le préfixe S3, puis écris du CSV depuis un SELECT (c'est le pipeline habituel « exporter DynamoDB vers S3 puis vers CSV »). AWS note que « de nombreux services AWS, comme Athena et AWS Glue, analyseront ce format automatiquement » (format de sortie d'export).
  • Fais-le toi-même — décompresse les fichiers .gz, parse chaque ligne JSON, et aplatis-la (même problème d'aplatissement que toute autre méthode).

C'est aussi un instantané de table entière : il n'y a aucun filtre côté serveur pour exporter seulement certains items. Si tu as besoin d'un sous-ensemble, soit tu filtres après coup dans Athena, soit tu utilises un script / un GUI à la place.

Méthode 3 : un script rapide (boto3 / Node)

Quand tu as besoin d'un CSV mis en forme — colonnes spécifiques, sous-ensemble filtré, traitement personnalisé des champs imbriqués — un petit script vaut mieux que se battre avec jq. L'avantage, c'est que les SDK AWS unmarshallent le JSON typé pour toi : l'interface resource de boto3 et le DynamoDBDocumentClient du SDK JS renvoient un simple {"price": 2000} au lieu de {"price": {"N": "2000"}} (l'interface resource de boto3 rend « le typage des données implicite », selon le guide Python d'AWS ; le DocumentClient JS « convertit les données de réponse annotées en types JavaScript natifs », selon @aws-sdk/lib-dynamodb).

import boto3, csv

table = boto3.resource("dynamodb").Table("MyTable")
rows, resp = [], table.scan()
rows += resp["Items"]
while "LastEvaluatedKey" in resp:                  # paginer jusqu'au bout
    resp = table.scan(ExclusiveStartKey=resp["LastEvaluatedKey"])
    rows += resp["Items"]

with open("out.csv", "w", newline="") as f:
    w = csv.DictWriter(f, fieldnames=["id", "name", "price"])
    w.writeheader()
    for r in rows:
        w.writerow({k: r.get(k) for k in w.fieldnames})

Tu gardes deux décisions que le SDK ne peut pas prendre à ta place : comment aplatir les maps/listes imbriquées en colonnes (encoder la cellule en JSON ? mettre les clés en dot-path ?), et quoi faire des attributs creux (ici une clé manquante devient une cellule vide via r.get(k)). Et ne supprime pas la boucle LastEvaluatedKey — un seul appel scan() ne renvoie que la première page de 1 Mo, donc sans elle tu exportes silencieusement une partie de la table.

Même réserve que pour la Méthode 1 : un scan de table entière consomme ici aussi de la capacité de lecture et entre en concurrence avec le trafic en direct. Pour une grosse table, préfère Méthode 2 et remets le dump en forme.

Méthode 4 : export en un clic dans DynoTable

Les voies script et CLI fonctionnent, mais tu reconstruis la même logique d'aplatissement et de pagination à chaque fois. DynoTable le fait pour toi : lance ou filtre une Query, puis exporte les lignes visibles directement en CSV (ou Excel) — descripteurs de type déballés, maps et listes imbriquées aplaties, sets gérés, et seulement les items et colonnes que tu veux réellement dans la sortie.

Parce que tu exportes la vue actuelle, tu obtiens le CSV filtré/mis en forme que l'instantané de table entière de Méthode 2 ne peut pas te donner — sans écrire de boucle de scan. C'est un client DynamoDB de bureau, le même outil que tu utilises déjà pour parcourir la table ; vois comment il se compare aux autres GUI DynamoDB.

Pièges : JSON DynamoDB vs CSV plat

Quelle que soit la méthode que tu choisis, la même poignée de décalages entre le modèle de données de DynamoDB et un CSV plat te piégera :

  • Descripteurs de type. La sortie brute API / CLI / export-S3 enveloppe chaque valeur ({"S": "..."}, {"N": "123"}). Soit tu la déballes via un SDK, soit tu retires toi-même le descripteur. Le jeu complet est S, N, B, BOOL, NULL, M, L, SS, NS, BS — voir types de données DynamoDB.
  • Les maps et listes imbriquées (M, L) peuvent s'imbriquer jusqu'à 32 niveaux de profondeur (docs AWS : types de données — list et map « peuvent être imbriqués l'un dans l'autre, pour représenter des structures de données complexes jusqu'à 32 niveaux de profondeur ») et n'ont pas de forme naturelle à colonne unique. Décide d'emblée : encoder la cellule en JSON, ou éclater les clés imbriquées en colonnes en dot-path (address.city).
  • Les sets (SS/NS/BS) sont des collections non ordonnées, pas des scalaires — AWS prévient que « l'ordre des valeurs au sein d'un set n'est pas préservé » (types de données) — donc aplatis vers une chaîne délimitée et ne te fie pas à l'ordre des éléments.
  • Attributs creux. DynamoDB est sans schéma, donc deux items peuvent avoir des attributs différents. Il n'y a pas de jeu de colonnes fixe ; fais l'union des clés sur tous les items ou les colonnes se décaleront. C'est une conséquence directe du single-table design, où une table contient plusieurs formes d'entités.
  • Pagination. Scan (et Query) renvoient au plus 1 Mo par appel. Si tu ne boucles pas sur LastEvaluatedKey, tu exporteras silencieusement seulement la première page. Voir pagination.
  • Précision numérique. Les nombres DynamoDB portent jusqu'à 38 chiffres de précision et voyagent sous forme de chaînes (docs AWS : types de données : « Les nombres peuvent avoir jusqu'à 38 chiffres de précision » ; « Tous les nombres sont envoyés à DynamoDB sur le réseau sous forme de chaînes ») ; un tableur peut convertir les longs nombres ou identifiants en flottants et perdre des chiffres. Garde-les en texte.

FAQ

Comment exporter une table DynamoDB en CSV avec l'AWS CLI ? Scanne la table et remodèle la sortie avec jq (Méthode 1) : aws dynamodb scanjq pour retirer le descripteur de type de chaque valeur → @csv. Il n'y a pas de --output csv conscient de DynamoDB, donc tu fais toujours le retrait de type toi-même, et ça casse sur les maps, listes et sets imbriqués.

Puis-je exporter une table DynamoDB directement en CSV depuis AWS ? Pas en une seule étape. La console et l'export S3 managé produisent tous deux du JSON DynamoDB ou de l'Amazon Ion, jamais du CSV. Tu as toujours besoin d'une étape de conversion — CLI + jq, un script, Athena/Glue sur le dump S3, ou un GUI qui fait l'aplatissement pour toi.

Comment exporter une table DynamoDB entière sans affecter la production ? Utilise la fonctionnalité d'export vers S3 (Méthode 2). Elle s'exécute de façon asynchrone et ne consomme aucune unité de capacité de lecture, donc elle n'entre pas en concurrence avec le trafic en direct — contrairement à un Scan, qui est facturé sur le débit de ta table (docs AWS). Elle exige que le PITR soit activé et exporte la table entière, pas un sous-ensemble filtré.

Comment exporter DynamoDB vers S3 en CSV ? L'export managé n'écrit que du JSON DynamoDB / Ion vers S3, donc « vers CSV » est un second saut : enregistre le préfixe d'export comme une table Athena (ou Glue) et écris du CSV depuis un SELECT. Il n'y a pas de --export-format CSV.

Comment exporter DynamoDB vers Excel ? Exporte d'abord en CSV (n'importe quelle méthode ci-dessus), puis ouvre le CSV dans Excel — en gardant les longs identifiants numériques en texte pour qu'ils ne soient pas convertis en flottants. Il n'y a pas d'export .xlsx direct depuis DynamoDB ; un GUI comme DynoTable peut enregistrer la vue actuelle directement dans un CSV prêt pour le tableur.

Pourquoi mon JSON exporté a-t-il {"S": ...} et {"N": ...} partout ? C'est le format de fil marshallé de DynamoDB — chaque valeur est taguée avec un descripteur de type. Unmarshalle-le avec un SDK, le convertisseur JSON DynamoDB, ou un GUI avant d'écrire du CSV. Le format de fil est le même que les données viennent de l'API, de la CLI ou de l'export S3.

Parcours, filtre et exporte tes propres tables en CSV avec DynoTable, ou déballe d'abord un échantillon de JSON DynamoDB dans le convertisseur JSON.

Mis à jour