Einsteiger10 Min. Lesezeit

So exportierst du eine DynamoDB-Tabelle nach CSV (4 Wege)

DynamoDB hat keinen nativen „Export nach CSV"-Button. Jeder Wert kommt in DynamoDBs marshalled JSON verpackt zurück — {"S": "..."}, {"N": "123"}, {"M": {...}} — und eine Tabelle kann verschachtelte Maps, Listen und Sets ohne offensichtliche flache Spaltenrepräsentation enthalten. „DynamoDB nach CSV exportieren" sind also eigentlich zwei Probleme: die Items herausholen und dann das getypte JSON in Zeilen flach klopfen. Weder die Konsole noch der verwaltete Export erledigt den zweiten Schritt für dich.

Dieser Leitfaden ordnet vier Ansätze nach Tabellengröße und danach, wie viel Verschachtelung deine Items tragen.

Wie exportiere ich eine DynamoDB-Tabelle nach CSV?

DynamoDB bietet keinen nativen CSV-Export — du scannst die Tabelle oder erstellst einen Snapshot und flachst dann das getypte JSON in Zeilen um. Für eine kleine Tabelle nutzt du AWS-CLI-scan + jq oder ein kurzes Skript; für große Tabellen exportierst du nach S3 und konvertierst dort; für ein gefiltertes, fertig aufbereitetes CSV verwendest du ein GUI-Tool wie DynoTable.

  • Kleine Tabelle, ad-hoc: AWS-CLI-scan + jq, oder ein 20-Zeilen-Skript (Methode 1 / Methode 3). Gut, bis verschachtelte Attribute auftauchen.
  • Große Tabelle (GBs+): DynamoDB-Export nach S3 (Methode 2), dann den Dump konvertieren. Läuft asynchron und verbraucht keine Lesekapazität — gibt aber DynamoDB-JSON aus, kein CSV.
  • Gefiltertes / geformtes CSV (eine Teilmenge der Spalten, nur einige Items): ein GUI-Export oder ein Skript. Der verwaltete S3-Export gibt dir die gesamte Tabelle, ungefiltert.

Methode 1: AWS-CLI-Scan + jq

Für eine kleine Tabelle kannst du sie scannen und die Ausgabe mit jq umformen. Ein Scan liest jedes Item der Tabelle und gibt es in Seiten von bis zu 1 MB zurück; die CLI folgt der Paginierung automatisch für dich (AWS-Doku: Scanning tables).

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

Der Haken steckt in dieser jq-Zeile: Du musst .id.S, .name.S, .price.N von Hand schreiben — am Typ-Deskriptor jedes Attributs (S, N, B, BOOL, M, L, SS, NS, BS) vorbeigreifen, um an den Rohwert zu kommen. Das ist handhabbar für eine flache Tabelle mit drei String-Spalten. Es fällt in dem Moment auseinander, in dem du Folgendes hast:

  • Verschachtelte Maps/Listen{"M": {...}} oder {"L": [...]} haben keine einzelne Spalte zum Flachklopfen; @csv verschluckt sich, oder du JSON-kodierst die Zelle von Hand.
  • Sets{"SS": ["a","b"]} ist ein Array, kein Skalar.
  • Spärliche Attribute — DynamoDB ist schemalos, also kann Item A einen price haben und Item B nicht. Deine feste Spaltenliste lässt stillschweigend Spalten weg oder verschiebt sie.

Es gibt auch kein --output csv, das DynamoDB-Typen versteht. Die csv-Ausgabe der CLI klopft die rohe Antwort flach, Deskriptoren und alles — also brauchst du weiterhin jq (oder ein Skript), um die Typ-Tags abzustreifen. Das ist der Kerngrund, warum „DynamoDB-Tabelle nach CSV exportieren per AWS CLI" jenseits des Trivialfalls nie ein Einzeiler ist.

Um eine ganze größere Tabelle auf diesem Weg zu exportieren, ohne dass es den ganzen Tag dauert, parallelisiere den Scan mit --segment / --total-segments (AWS-Doku: Parallel scan — DynamoDB „weist Items Segmenten zu, indem es eine Hash-Funktion auf den Partition Key jedes Items anwendet", also können Segmente ungleichmäßig sein), und lies Paginierung, damit du nicht bei der ersten 1-MB-Seite stehen bleibst.

Methode 2: DynamoDB-Export nach S3 (große Tabellen)

Für Tabellen jeder echten Größe ist der verwaltete Export nach Amazon S3 das richtige Werkzeug. Er exportiert einen Snapshot aus einem beliebigen Zeitpunkt innerhalb deines Point-in-Time-Recovery-(PITR)-Fensters — also muss PITR auf der Tabelle zuerst aktiviert sein — läuft asynchron und verbraucht keine Read Capacity Units, hat also null Einfluss auf Durchsatz oder Verfügbarkeit deiner Tabelle (AWS-Doku: „Exporte sind asynchron, sie verbrauchen keine Read Capacity Units (RCUs) und haben keinen Einfluss auf Tabellen-Performance und -Verfügbarkeit"; „Du musst PITR auf deiner Tabelle aktivieren, um die Export-Funktionalität zu nutzen"). Das ist auch, was die Exports-to-S3-Aktion der Konsole unter der Haube auslöst: Die Konsole ist nur ein Frontend für dieselbe API, sie trägt also dieselbe PITR-Anforderung und dieselbe JSON-Ausgabe.

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

Der eine Haken: Der S3-Export gibt kein CSV aus. Er schreibt DynamoDB-JSON oder Amazon Ion ausschließlich, als gzip-Dateien im JSON-Lines-Format (ein Item pro Zeile), plus Manifest-Dateien (AWS-Doku: export output format — Datendateien werden als .json.gz geschrieben, „das Format ist JSON Lines", neben manifest-summary.json / manifest-files.json). Du brauchst danach weiterhin einen Konvertierungsschritt:

  • Athena / Glue lesen das exportierte DynamoDB-JSON direkt — richte eine Tabelle auf das S3-Präfix, dann schreibe CSV aus einem SELECT (das ist die übliche „DynamoDB nach S3 dann nach CSV"-Pipeline). AWS merkt an, dass „viele AWS-Services, etwa Athena und AWS Glue, dieses Format automatisch parsen" (export output format).
  • Selbst bauen — die .gz-Dateien dekomprimieren, jede JSON-Zeile parsen und sie flachklopfen (dasselbe Flachklopf-Problem wie bei jeder anderen Methode).

Es ist außerdem ein **vollständiger Tabellen-**Snapshot: Es gibt keinen serverseitigen Filter, um nur einige Items zu exportieren. Wenn du eine Teilmenge brauchst, filterst du entweder nachträglich in Athena, oder du nutzt ein Skript / GUI.

Methode 3: ein schnelles Skript (boto3 / Node)

Wenn du ein geformtes CSV brauchst — bestimmte Spalten, eine gefilterte Teilmenge, eigene Behandlung verschachtelter Felder — schlägt ein kleines Skript den Kampf mit jq. Der Gewinn ist, dass die AWS-SDKs das getypte JSON für dich unmarshallen: boto3s Resource-Interface und der DynamoDBDocumentClient des JS-SDK geben schlichtes {"price": 2000} statt {"price": {"N": "2000"}} zurück (boto3s Resource-Interface macht „die Typisierung der Daten implizit", laut AWS Python guide; der JS DocumentClient „konvertiert annotierte Antwortdaten in native JavaScript-Typen", laut @aws-sdk/lib-dynamodb).

import boto3, csv

table = boto3.resource("dynamodb").Table("MyTable")
rows, resp = [], table.scan()
rows += resp["Items"]
while "LastEvaluatedKey" in resp:                  # bis zum Ende paginieren
    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})

Du besitzt weiterhin zwei Entscheidungen, die das SDK nicht für dich treffen kann: wie du verschachtelte Maps/Listen in Spalten flachklopfst (die Zelle JSON-kodieren? die Schlüssel als Dot-Pfad?), und was du mit spärlichen Attributen machst (hier wird ein fehlender Schlüssel über r.get(k) zu einer leeren Zelle). Und lass die LastEvaluatedKey-Schleife nicht weg — ein einzelner scan()-Aufruf liefert nur die erste 1-MB-Seite, also exportierst du ohne sie stillschweigend nur einen Teil der Tabelle.

Gleicher Vorbehalt wie Methode 1: Ein vollständiger Tabellen-scan verbraucht hier weiterhin Lesekapazität und konkurriert mit Live-Traffic. Für eine große Tabelle bevorzuge Methode 2 und forme den Dump um.

Methode 4: Ein-Klick-Export in DynoTable

Die Skript- und CLI-Wege funktionieren, aber du baust jedes Mal dieselbe Flachklopf- und Paginierungslogik neu. DynoTable erledigt es für dich: Führe eine Abfrage aus oder filtere sie, dann exportiere die sichtbaren Zeilen direkt nach CSV (oder Excel) — Typ-Deskriptoren ausgepackt, verschachtelte Maps und Listen flachgeklopft, Sets behandelt, und nur die Items und Spalten, die du tatsächlich in der Ausgabe willst.

Weil du die aktuelle Ansicht exportierst, bekommst du das gefilterte/geformte CSV, das der vollständige Tabellen-Snapshot von Methode 2 nicht liefern kann — ohne eine Scan-Schleife zu schreiben. Es ist ein Desktop-DynamoDB-Client, dasselbe Tool, mit dem du die Tabelle ohnehin schon durchsuchst; sieh dir an, wie es mit anderen DynamoDB-GUIs abschneidet.

Stolperfallen: DynamoDB-JSON vs flaches CSV

Welche Methode du auch wählst, dieselbe Handvoll Diskrepanzen zwischen DynamoDBs Datenmodell und einem flachen CSV wird dich beißen:

  • Typ-Deskriptoren. Rohe API- / CLI- / S3-Export-Ausgabe verpackt jeden Wert ({"S": "..."}, {"N": "123"}). Du packst ihn entweder über ein SDK aus oder streifst den Deskriptor selbst ab. Der vollständige Satz ist S, N, B, BOOL, NULL, M, L, SS, NS, BS — siehe DynamoDB-Datentypen.
  • Verschachtelte Maps und Listen (M, L) können bis zu 32 Ebenen tief verschachtelt sein (AWS-Doku: data types — Liste und Map „können ineinander verschachtelt werden, um komplexe Datenstrukturen bis zu 32 Ebenen tief darzustellen") und haben keine natürliche Einzelspaltenform. Entscheide vorab: die Zelle JSON-kodieren oder verschachtelte Schlüssel in Dot-Pfad-Spalten auffächern (address.city).
  • Sets (SS/NS/BS) sind ungeordnete Sammlungen, keine Skalare — AWS warnt „die Reihenfolge der Werte innerhalb eines Sets bleibt nicht erhalten" (data types) — also klopfe zu einem getrennten String flach und verlasse dich nicht auf die Element-Reihenfolge.
  • Spärliche Attribute. DynamoDB ist schemalos, also können zwei Items unterschiedliche Attribute haben. Es gibt keinen festen Spaltensatz; bilde die Vereinigung der Schlüssel über alle Items, sonst verschieben sich die Spalten. Das ist eine direkte Folge von Single-Table-Design, wo eine Tabelle mehrere Entitätsformen enthält.
  • Paginierung. Scan (und Query) geben höchstens 1 MB pro Aufruf zurück. Wenn du nicht über LastEvaluatedKey schleifst, exportierst du stillschweigend nur die erste Seite. Siehe Paginierung.
  • Zahlengenauigkeit. DynamoDB-Zahlen tragen bis zu 38 Stellen Genauigkeit und reisen als Strings (AWS-Doku: data types: „Zahlen können bis zu 38 Stellen Genauigkeit haben"; „Alle Zahlen werden als Strings über das Netzwerk an DynamoDB gesendet"); Tabellensoftware kann lange Zahlen oder IDs zu Floats coercen und Stellen verlieren. Behalte sie als Text.

FAQ

Wie exportiere ich eine DynamoDB-Tabelle mit der AWS CLI nach CSV? Scanne die Tabelle und forme die Ausgabe mit jq um (Methode 1): aws dynamodb scanjq, um den Typ-Deskriptor jedes Werts abzustreifen → @csv. Es gibt kein DynamoDB-bewusstes --output csv, also machst du das Typ-Abstreifen immer selbst, und es bricht bei verschachtelten Maps, Listen und Sets.

Kann ich eine DynamoDB-Tabelle direkt aus AWS nach CSV exportieren? Nicht in einem Schritt. Die Konsole und der verwaltete S3-Export erzeugen beide DynamoDB-JSON oder Amazon Ion, nie CSV. Du brauchst immer einen Konvertierungsschritt — CLI + jq, ein Skript, Athena/Glue über den S3-Dump oder eine GUI, die das Flachklopfen für dich macht.

Wie exportiere ich eine ganze DynamoDB-Tabelle, ohne die Produktion zu beeinträchtigen? Nutze das Export-nach-S3-Feature (Methode 2). Es läuft asynchron und verbraucht keine Read Capacity Units, konkurriert also nicht mit Live-Traffic — anders als ein Scan, der gegen den Durchsatz deiner Tabelle gemessen wird (AWS-Doku). Es erfordert aktiviertes PITR und exportiert die ganze Tabelle, keine gefilterte Teilmenge.

Wie exportiere ich DynamoDB als CSV nach S3? Der verwaltete Export schreibt nur DynamoDB-JSON / Ion nach S3, „nach CSV" ist also ein zweiter Sprung: Registriere das Export-Präfix als Athena-(oder Glue-)Tabelle und schreibe CSV aus einem SELECT. Es gibt kein --export-format CSV.

Wie exportiere ich DynamoDB nach Excel? Exportiere zuerst nach CSV (jede Methode oben), dann öffne das CSV in Excel — und behalte lange numerische IDs als Text, damit sie nicht zu Floats gecoerced werden. Es gibt keinen direkten .xlsx-Export aus DynamoDB; eine GUI wie DynoTable kann die aktuelle Ansicht direkt als tabellenkalkulationsfertiges CSV speichern.

Warum hat mein exportiertes JSON überall {"S": ...} und {"N": ...}? Das ist DynamoDBs marshalled Wire-Format — jeder Wert ist mit einem Typ-Deskriptor getaggt. Unmarshalle es mit einem SDK, dem DynamoDB-JSON-Konverter oder einer GUI, bevor du CSV schreibst. Das Wire-Format ist dasselbe, ob die Daten aus der API, der CLI oder dem S3-Export kamen.

Durchsuche, filtere und exportiere deine eigenen Tabellen nach CSV mit DynoTable, oder packe zuerst ein Sample von DynamoDB-JSON im JSON-Konverter aus.

Aktualisiert