Iniciante11 min de leitura

Como Exportar uma Tabela DynamoDB para CSV (4 Formas)

O DynamoDB não tem um botão nativo de "exportar para CSV". Todo valor volta envolto no JSON marshalled do DynamoDB{"S": "..."}, {"N": "123"}, {"M": {...}} — e uma tabela pode conter mapas, listas e conjuntos aninhados sem nenhuma representação óbvia em colunas planas. Então "exportar o DynamoDB para CSV" é na verdade dois problemas: tirar os itens de lá e depois achatar o JSON tipado em linhas. Nem o console nem a exportação gerenciada fazem o segundo passo por você.

Este guia ordena quatro abordagens pelo tamanho da tabela e por quanto aninhamento seus itens carregam.

Como faço para exportar uma tabela DynamoDB para CSV?

O DynamoDB não tem exportação nativa para CSV: você escaneia ou tira um snapshot da tabela e depois achata o JSON tipado em linhas. Para tabelas pequenas, use scan da AWS CLI + jq ou um script curto; para tabelas grandes, exporte para o S3 e converta; para um CSV filtrado e pronto, use uma interface gráfica como o DynoTable.

  • Tabela pequena, ad-hoc: scan da AWS CLI + jq, ou um script de 20 linhas (Método 1 / Método 3). Funciona até aparecerem atributos aninhados.
  • Tabela grande (GBs+): exportação do DynamoDB para o S3 (Método 2), depois converta o dump. Roda de forma assíncrona e não consome capacidade de leitura — mas emite JSON do DynamoDB, não CSV.
  • CSV filtrado / moldado (um subconjunto de colunas, apenas alguns itens): uma exportação por GUI ou um script. A exportação gerenciada para S3 te dá a tabela inteira, sem filtro.

Método 1: scan da AWS CLI + jq

Para uma tabela pequena, você pode escaneá-la e remodelar a saída com jq. Um Scantodo item da tabela e o retorna em páginas de até 1 MB; a CLI segue a paginação por você automaticamente (docs AWS: Scanning tables).

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

O problema está naquela linha do jq: você tem que escrever à mão .id.S, .name.S, .price.N — alcançando, atrás do descritor de tipo de cada atributo (S, N, B, BOOL, M, L, SS, NS, BS), o valor bruto. Isso é gerenciável para uma tabela plana com três colunas de string. Desmorona no momento em que você tem:

  • Mapas/listas aninhados{"M": {...}} ou {"L": [...]} não têm uma única coluna para achatar; o @csv engasga, ou você codifica a célula em JSON manualmente.
  • Conjuntos{"SS": ["a","b"]} é um array, não um escalar.
  • Atributos esparsos — o DynamoDB não tem schema, então o item A pode ter um price e o item B pode não ter. Sua lista fixa de colunas silenciosamente descarta ou desalinha colunas.

Também não há um --output csv que entenda os tipos do DynamoDB. A saída csv da CLI achata a resposta bruta, descritores e tudo — então você ainda precisa do jq (ou de um script) para tirar os marcadores de tipo. Essa é a razão central de "exportar tabela DynamoDB para CSV via AWS CLI" nunca ser um one-liner além do caso trivial.

Para exportar uma tabela maior inteira por este caminho sem demorar o dia todo, paralelize o scan com --segment / --total-segments (docs AWS: Parallel scan — o DynamoDB "atribui itens a segmentos aplicando uma função hash à chave de partição de cada item", então os segmentos podem ficar desiguais), e leia paginação para não parar na primeira página de 1 MB.

Método 2: exportação do DynamoDB para o S3 (tabelas grandes)

Para tabelas de qualquer tamanho real, a exportação gerenciada para o Amazon S3 é a ferramenta certa. Ela exporta um snapshot de qualquer ponto da sua janela de recuperação point-in-time (PITR) — então o PITR precisa estar habilitado na tabela primeiro — roda de forma assíncrona e não consome unidades de capacidade de leitura, sem impacto na taxa de transferência ou na disponibilidade da sua tabela (docs AWS: "As exportações são assíncronas, não consomem unidades de capacidade de leitura (RCUs) e não têm impacto no desempenho e na disponibilidade da tabela"; "Você precisa habilitar o PITR na sua tabela para usar a funcionalidade de exportação"). É também o que a ação Exports to S3 do console dispara por baixo dos panos: o console é só uma interface para a mesma API, então carrega o mesmo requisito de PITR e a mesma saída em 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

A única pegadinha: a exportação para o S3 não gera CSV. Ela escreve JSON do DynamoDB ou Amazon Ion apenas, como arquivos gzipados no formato JSON-lines (um item por linha), além de arquivos de manifesto (docs AWS: formato de saída da exportação — os arquivos de dados são escritos como .json.gz, "o formato é JSON lines", ao lado de manifest-summary.json / manifest-files.json). Você ainda precisa de um passo de conversão depois:

  • Athena / Glue leem o JSON do DynamoDB exportado diretamente — aponte uma tabela para o prefixo do S3 e depois escreva CSV a partir de um SELECT (este é o pipeline usual de "exportar DynamoDB para o S3 e depois para CSV"). A AWS observa que "muitos serviços AWS, como o Athena e o AWS Glue, fazem o parsing desse formato automaticamente" (formato de saída da exportação).
  • Faça você mesmo — descompacte os arquivos .gz, faça o parsing de cada linha JSON e achate-a (o mesmo problema de achatamento de todos os outros métodos).

É também um snapshot de tabela inteira: não há filtro do lado do servidor para exportar só alguns itens. Se você precisa de um subconjunto, ou filtra depois no Athena, ou usa um script / GUI.

Método 3: um script rápido (boto3 / Node)

Quando você precisa de um CSV moldado — colunas específicas, um subconjunto filtrado, tratamento personalizado de campos aninhados — um pequeno script ganha de brigar com o jq. A vantagem é que os SDKs da AWS fazem o unmarshall do JSON tipado por você: a interface de resource do boto3 e o DynamoDBDocumentClient do SDK JS retornam {"price": 2000} simples em vez de {"price": {"N": "2000"}} (a interface de resource do boto3 torna "a tipagem dos dados implícita", conforme o guia Python da AWS; o DocumentClient JS "converte os dados anotados da resposta em tipos nativos do JavaScript", conforme o @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 até o fim
    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})

Você ainda é dono de duas decisões que o SDK não pode tomar por você: como achatar mapas/listas aninhados em colunas (codificar a célula em JSON? usar dot-path nas chaves?), e o que fazer com atributos esparsos (aqui uma chave ausente vira uma célula vazia via r.get(k)). E não largue o loop do LastEvaluatedKey — uma única chamada scan() retorna apenas a primeira página de 1 MB, então sem ele você exporta silenciosamente parte da tabela.

Mesma ressalva do Método 1: um scan de tabela inteira aqui ainda consome capacidade de leitura e compete com o tráfego ao vivo. Para uma tabela grande, prefira o Método 2 e remodele o dump.

Método 4: exportação com um clique no DynoTable

As rotas de script e CLI funcionam, mas você reconstrói a mesma lógica de achatamento e paginação toda vez. O DynoTable faz isso por você: rode ou filtre uma Query, depois exporte as linhas visíveis direto para CSV (ou Excel) — descritores de tipo desembrulhados, mapas e listas aninhados achatados, conjuntos tratados, e apenas os itens e colunas que você realmente quer na saída.

Como você exporta a visão atual, você obtém o CSV filtrado/moldado que o snapshot de tabela inteira do Método 2 não pode te dar — sem escrever um loop de scan. É um cliente desktop de DynamoDB, a mesma ferramenta que você já usa para navegar pela tabela; veja como ele se compara a outras GUIs de DynamoDB.

Pegadinhas: JSON do DynamoDB vs CSV plano

Qualquer que seja o método escolhido, o mesmo punhado de descompassos entre o modelo de dados do DynamoDB e um CSV plano vai te morder:

  • Descritores de tipo. A saída bruta da API / CLI / exportação para S3 envolve todo valor ({"S": "..."}, {"N": "123"}). Você ou faz o unmarshall via um SDK ou tira o descritor você mesmo. O conjunto completo é S, N, B, BOOL, NULL, M, L, SS, NS, BS — veja tipos de dados do DynamoDB.
  • Mapas e listas aninhados (M, L) podem aninhar até 32 níveis de profundidade (docs AWS: tipos de dados — list e map "podem ser aninhados um dentro do outro, para representar estruturas de dados complexas com até 32 níveis de profundidade") e não têm uma forma natural de coluna única. Decida de antemão: codifique a célula em JSON, ou explode as chaves aninhadas em colunas com dot-path (address.city).
  • Conjuntos (SS/NS/BS) são coleções não ordenadas, não escalares — a AWS avisa que "a ordem dos valores dentro de um conjunto não é preservada" (tipos de dados) — então achate para uma string delimitada e não confie na ordem dos elementos.
  • Atributos esparsos. O DynamoDB não tem schema, então dois itens podem ter atributos diferentes. Não há conjunto fixo de colunas; faça a união das chaves de todos os itens ou as colunas vão desalinhar. Isso é uma consequência direta do single-table design, em que uma tabela contém vários formatos de entidade.
  • Paginação. Scan (e Query) retornam no máximo 1 MB por chamada. Se você não fizer o loop no LastEvaluatedKey, vai exportar silenciosamente só a primeira página. Veja paginação.
  • Precisão numérica. Os números do DynamoDB carregam até 38 dígitos de precisão e trafegam como strings (docs AWS: tipos de dados: "Os números podem ter até 38 dígitos de precisão"; "Todos os números são enviados pela rede ao DynamoDB como strings"); software de planilha pode coagir números longos ou IDs em floats e perder dígitos. Mantenha-os como texto.

FAQ

Como exporto uma tabela DynamoDB para CSV com a AWS CLI? Escaneie a tabela e remodele a saída com jq (Método 1): aws dynamodb scanjq para tirar o descritor de tipo de cada valor → @csv. Não há um --output csv ciente do DynamoDB, então você sempre faz a remoção de tipo você mesmo, e isso quebra em mapas, listas e conjuntos aninhados.

Posso exportar uma tabela DynamoDB direto para CSV pela AWS? Não em um passo. O console e a exportação gerenciada para S3 ambos produzem JSON do DynamoDB ou Amazon Ion, nunca CSV. Você sempre precisa de um passo de conversão — CLI + jq, um script, Athena/Glue sobre o dump do S3, ou uma GUI que faça o achatamento por você.

Como exporto uma tabela DynamoDB inteira sem afetar a produção? Use a funcionalidade de exportação para o S3 (Método 2). Ela roda de forma assíncrona e não consome unidades de capacidade de leitura, então não compete com o tráfego ao vivo — diferente de um Scan, que é tarifado contra a taxa de transferência da sua tabela (docs AWS). Requer que o PITR esteja habilitado e exporta a tabela inteira, não um subconjunto filtrado.

Como exporto o DynamoDB para o S3 como CSV? A exportação gerenciada só escreve JSON do DynamoDB / Ion no S3, então "para CSV" é um segundo salto: registre o prefixo da exportação como uma tabela do Athena (ou Glue) e escreva CSV a partir de um SELECT. Não há --export-format CSV.

Como exporto o DynamoDB para o Excel? Exporte para CSV primeiro (qualquer método acima), depois abra o CSV no Excel — mantendo IDs numéricos longos como texto para que não sejam coagidos em floats. Não há exportação .xlsx direta do DynamoDB; uma GUI como o DynoTable pode salvar a visão atual direto em um CSV pronto para planilha.

Por que meu JSON exportado tem {"S": ...} e {"N": ...} em todo lugar? Esse é o formato de transmissão marshalled do DynamoDB — cada valor é marcado com um descritor de tipo. Faça o unmarshall com um SDK, o conversor de JSON do DynamoDB, ou uma GUI antes de escrever o CSV. O formato de transmissão é o mesmo, quer os dados venham da API, da CLI ou da exportação para o S3.

Navegue, filtre e exporte suas próprias tabelas para CSV com o DynoTable, ou desembrulhe uma amostra de JSON do DynamoDB no conversor de JSON primeiro.

Atualizado