Principiante11 min di lettura

Come esportare una tabella DynamoDB in CSV (4 modi)

DynamoDB non ha un pulsante nativo "esporta in CSV". Ogni valore torna avvolto nel JSON marshalled di DynamoDB{"S": "..."}, {"N": "123"}, {"M": {...}} — e una tabella può contenere mappe, liste e set annidati senza una rappresentazione a colonne piatte ovvia. Quindi "esportare DynamoDB in CSV" sono in realtà due problemi: tirare fuori gli elementi, poi appiattire il JSON tipizzato in righe. Né la console né l'export gestito fanno il secondo passaggio per te.

Questa guida classifica quattro approcci per dimensione della tabella e per quanta nidificazione portano i tuoi elementi.

Come si esporta una tabella DynamoDB in CSV?

DynamoDB non dispone di un export CSV nativo: devi eseguire la scansione o uno snapshot della tabella, poi appiattire il suo JSON tipizzato in righe. Per una tabella piccola usa AWS CLI scan + jq o un breve script; per tabelle grandi, esporta su S3 e converti; per un CSV filtrato e già pronto, usa una GUI come DynoTable.

  • Tabella piccola, ad hoc: AWS CLI scan + jq, o uno script di 20 righe (Metodo 1 / Metodo 3). Va bene finché non compaiono attributi annidati.
  • Tabella grande (GB+): export DynamoDB su S3 (Metodo 2), poi converti il dump. Gira in modo asincrono e non consuma capacità di lettura — ma produce JSON DynamoDB, non CSV.
  • CSV filtrato / sagomato (un sottoinsieme di colonne, solo alcuni elementi): un export da GUI o uno script. L'export gestito su S3 ti dà la tabella intera, non filtrata.

Metodo 1: AWS CLI scan + jq

Per una tabella piccola puoi farne lo scan e rimodellare l'output con jq. Uno Scan legge ogni elemento della tabella e lo restituisce in pagine fino a 1 MB; la CLI segue la paginazione per te automaticamente (documentazione AWS: scansione delle tabelle).

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

L'inghippo è in quella riga jq: devi scrivere a mano .id.S, .name.S, .price.N — andando oltre il descrittore di tipo di ogni attributo (S, N, B, BOOL, M, L, SS, NS, BS) per ottenere il valore grezzo. È gestibile per una tabella piatta con tre colonne stringa. Crolla nel momento in cui hai:

  • Mappe/liste annidate{"M": {...}} o {"L": [...]} non hanno una singola colonna in cui appiattirsi; @csv si inceppa, oppure codifichi la cella in JSON a mano.
  • Set{"SS": ["a","b"]} è un array, non uno scalare.
  • Attributi sparsi — DynamoDB è senza schema, quindi l'elemento A può avere un price e l'elemento B no. La tua lista fissa di colonne elimina o disallinea silenziosamente le colonne.

Non esiste nemmeno un --output csv che capisca i tipi DynamoDB. L'output csv della CLI appiattisce la risposta grezza, descrittori inclusi — quindi ti serve comunque jq (o uno script) per togliere i tag di tipo. Questo è il motivo fondamentale per cui "esportare una tabella DynamoDB in CSV via AWS CLI" non è mai un one-liner oltre il caso banale.

Per esportare un'intera tabella più grande in questo modo senza metterci tutto il giorno, parallelizza lo scan con --segment / --total-segments (documentazione AWS: scansione parallela — DynamoDB "assegna gli elementi ai segmenti applicando una funzione hash alla chiave di partizione di ciascun elemento", quindi i segmenti possono essere disuguali), e leggi la paginazione così non ti fermi alla prima pagina da 1 MB.

Metodo 2: export DynamoDB su S3 (tabelle grandi)

Per tabelle di dimensioni reali, l'export gestito su Amazon S3 è lo strumento giusto. Esporta uno snapshot da qualsiasi punto della tua finestra di point-in-time recovery (PITR) — quindi PITR deve essere abilitato sulla tabella prima — gira in modo asincrono e non consuma unità di capacità di lettura, quindi ha impatto zero sul throughput o sulla disponibilità della tua tabella (documentazione AWS: "Gli export sono asincroni, non consumano unità di capacità di lettura (RCU) e non hanno impatto sulle prestazioni e sulla disponibilità della tabella"; "Devi abilitare PITR sulla tua tabella per usare la funzionalità di export"). È anche ciò che l'azione Exports to S3 della console attiva sotto il cofano: la console è solo un front end per la stessa API, quindi porta con sé lo stesso requisito PITR e lo stesso output 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

L'unico inghippo: l'export su S3 non produce CSV. Scrive solo JSON DynamoDB o Amazon Ion, come file gzippati in formato JSON-lines (un elemento per riga), più file di manifest (documentazione AWS: formato di output dell'export — i file dati sono scritti come .json.gz, "il formato è JSON lines", insieme a manifest-summary.json / manifest-files.json). Ti serve comunque un passaggio di conversione successivo:

  • Athena / Glue leggono direttamente il JSON DynamoDB esportato — punta una tabella al prefisso S3, poi scrivi CSV da una SELECT (questa è la solita pipeline "esporta DynamoDB su S3 poi su CSV"). AWS nota che "molti servizi AWS, come Athena e AWS Glue, analizzeranno questo formato automaticamente" (formato di output dell'export).
  • Fai da te — decomprimi i file .gz, analizza ogni riga JSON e appiattiscila (lo stesso problema di appiattimento di ogni altro metodo).

È anche uno snapshot dell'intera tabella: non c'è filtro lato server per esportare solo alcuni elementi. Se ti serve un sottoinsieme, filtri a posteriori in Athena, oppure usi uno script / una GUI.

Metodo 3: uno script veloce (boto3 / Node)

Quando ti serve un CSV sagomato — colonne specifiche, un sottoinsieme filtrato, gestione personalizzata per i campi annidati — un piccolo script batte la lotta con jq. Il vantaggio è che gli SDK di AWS fanno l'unmarshalling del JSON tipizzato per te: l'interfaccia resource di boto3 e il DynamoDBDocumentClient del JS SDK restituiscono un semplice {"price": 2000} invece di {"price": {"N": "2000"}} (l'interfaccia resource di boto3 rende "la tipizzazione dei dati implicita", secondo la guida AWS Python; il DocumentClient JS "converte i dati di risposta annotati in tipi JavaScript nativi", secondo @aws-sdk/lib-dynamodb).

import boto3, csv

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

Restano due decisioni di tua proprietà che l'SDK non può prendere per te: come appiattire mappe/liste annidate in colonne (codificare la cella in JSON? mettere le chiavi in dot-path?), e cosa fare con gli attributi sparsi (qui una chiave mancante diventa una cella vuota tramite r.get(k)). E non perdere il loop su LastEvaluatedKey — una singola chiamata scan() restituisce solo la prima pagina da 1 MB, quindi senza di esso esporti silenziosamente solo una parte della tabella.

Stessa avvertenza del Metodo 1: uno scan dell'intera tabella qui consuma comunque capacità di lettura e compete con il traffico live. Per una tabella grande, preferisci Metodo 2 e rimodella il dump.

Metodo 4: export con un clic in DynoTable

Le strade dello script e della CLI funzionano, ma ricostruisci ogni volta la stessa logica di appiattimento e paginazione. DynoTable lo fa per te: esegui o filtra una query, poi esporta le righe visibili direttamente in CSV (o Excel) — i descrittori di tipo srotolati, mappe e liste annidate appiattite, i set gestiti, e solo gli elementi e le colonne che vuoi davvero nell'output.

Poiché esporti la vista corrente, ottieni il CSV filtrato/sagomato che lo snapshot dell'intera tabella del Metodo 2 non può darti — senza scrivere un loop di scan. È un client DynamoDB desktop, lo stesso strumento che già usi per sfogliare la tabella; vedi come si confronta con altre GUI DynamoDB.

Inghippi: JSON DynamoDB vs CSV piatto

Qualunque metodo tu scelga, la stessa manciata di disallineamenti tra il modello dati di DynamoDB e un CSV piatto ti morderà:

  • Descrittori di tipo. L'output grezzo di API / CLI / export-S3 avvolge ogni valore ({"S": "..."}, {"N": "123"}). O lo srotoli tramite un SDK o togli tu stesso il descrittore. L'insieme completo è S, N, B, BOOL, NULL, M, L, SS, NS, BS — vedi tipi di dati DynamoDB.
  • Mappe e liste annidate (M, L) possono annidarsi fino a 32 livelli di profondità (documentazione AWS: tipi di dati — lista e mappa "possono essere annidate l'una nell'altra, per rappresentare strutture dati complesse fino a 32 livelli di profondità") e non hanno una forma naturale a colonna singola. Decidi in anticipo: codifica la cella in JSON, o esplodi le chiavi annidate in colonne con dot-path (address.city).
  • Set (SS/NS/BS) sono collezioni non ordinate, non scalari — AWS avverte che "l'ordine dei valori all'interno di un set non viene preservato" (tipi di dati) — quindi appiattisci a una stringa delimitata e non fare affidamento sull'ordine degli elementi.
  • Attributi sparsi. DynamoDB è senza schema, quindi due elementi possono avere attributi diversi. Non c'è un set fisso di colonne; unisci le chiavi su tutti gli elementi o le colonne si disallineeranno. Questa è una conseguenza diretta del single-table design, dove una tabella contiene diverse forme di entità.
  • Paginazione. Scan (e Query) restituiscono al massimo 1 MB per chiamata. Se non fai il loop su LastEvaluatedKey esporterai silenziosamente solo la prima pagina. Vedi paginazione.
  • Precisione numerica. I numeri DynamoDB portano fino a 38 cifre di precisione e viaggiano come stringhe (documentazione AWS: tipi di dati: "I numeri possono avere fino a 38 cifre di precisione"; "Tutti i numeri vengono inviati attraverso la rete a DynamoDB come stringhe"); i software per fogli di calcolo possono forzare numeri o ID lunghi in float e perdere cifre. Tienili come testo.

FAQ

Come esporto una tabella DynamoDB in CSV con la AWS CLI? Fai lo scan della tabella e rimodella l'output con jq (Metodo 1): aws dynamodb scanjq per togliere il descrittore di tipo di ogni valore → @csv. Non c'è un --output csv consapevole di DynamoDB, quindi fai sempre tu il togliere-il-tipo, e si rompe su mappe, liste e set annidati.

Posso esportare una tabella DynamoDB direttamente in CSV da AWS? Non in un solo passaggio. La console e l'export gestito su S3 producono entrambi JSON DynamoDB o Amazon Ion, mai CSV. Ti serve sempre un passaggio di conversione — CLI + jq, uno script, Athena/Glue sul dump S3, o una GUI che faccia l'appiattimento per te.

Come esporto un'intera tabella DynamoDB senza impattare la produzione? Usa la funzionalità di export su S3 (Metodo 2). Gira in modo asincrono e non consuma unità di capacità di lettura, quindi non compete con il traffico live — a differenza di uno Scan, che è misurato sul throughput della tua tabella (documentazione AWS). Richiede che PITR sia abilitato ed esporta l'intera tabella, non un sottoinsieme filtrato.

Come esporto DynamoDB su S3 come CSV? L'export gestito scrive solo JSON DynamoDB / Ion su S3, quindi "in CSV" è un secondo salto: registra il prefisso dell'export come tabella Athena (o Glue) e scrivi CSV da una SELECT. Non esiste un --export-format CSV.

Come esporto DynamoDB in Excel? Esporta prima in CSV (qualsiasi metodo sopra), poi apri il CSV in Excel — tenendo gli ID numerici lunghi come testo così non vengono forzati in float. Non c'è un export .xlsx diretto da DynamoDB; una GUI come DynoTable può salvare la vista corrente direttamente in un CSV pronto per il foglio di calcolo.

Perché il mio JSON esportato ha {"S": ...} e {"N": ...} dappertutto? Quello è il formato marshalled su rete di DynamoDB — ogni valore è etichettato con un descrittore di tipo. Srotolalo con un SDK, con il convertitore JSON DynamoDB, o con una GUI prima di scrivere il CSV. Il formato su rete è lo stesso sia che i dati vengano dall'API, dalla CLI o dall'export S3.

Sfoglia, filtra ed esporta le tue tabelle in CSV con DynoTable, o srotola prima un campione di JSON DynamoDB nel convertitore JSON.

Aggiornato