Principiante12 min de lectura

Cómo exportar una tabla de DynamoDB a CSV (4 maneras)

DynamoDB no tiene un botón nativo de «exportar a CSV». Cada valor vuelve envuelto en el JSON marshalled de DynamoDB{"S": "..."}, {"N": "123"}, {"M": {...}} — y una tabla puede contener mapas, listas y conjuntos anidados sin una representación de columna plana evidente. Así que «exportar DynamoDB a CSV» son en realidad dos problemas: sacar los Items, y luego aplanar el JSON tipado en filas. Ni la consola ni la exportación gestionada hacen el segundo paso por ti.

Esta guía clasifica cuatro enfoques según el tamaño de la tabla y según cuánto anidamiento acarrean tus Items.

¿Cómo exporto una tabla de DynamoDB a CSV?

DynamoDB no tiene exportación a CSV nativa, por lo que debes hacer un scan o una instantánea de la tabla y luego aplanar su JSON tipado en filas. Para una tabla pequeña, usa scan de AWS CLI + jq o un script corto; para tablas grandes, exporta a S3 y convierte; para un CSV filtrado y listo, usa una GUI como DynoTable.

  • Tabla pequeña, ad-hoc: scan de AWS CLI + jq, o un script de 20 líneas (Método 1 / Método 3). Sirve hasta que aparecen atributos anidados.
  • Tabla grande (GB+): exportación de DynamoDB a S3 (Método 2), y luego convertir el volcado. Se ejecuta de forma asíncrona y no consume capacidad de lectura — pero produce JSON de DynamoDB, no CSV.
  • CSV filtrado / con forma (un subconjunto de columnas, solo algunos Items): una exportación desde una GUI o un script. La exportación gestionada a S3 te da la tabla entera, sin filtrar.

Método 1: scan de AWS CLI + jq

Para una tabla pequeña puedes hacer un scan y reformar la salida con jq. Un Scan lee todos los Items de la tabla y los devuelve en páginas de hasta 1 MB; la CLI sigue la paginación por ti automáticamente (Docs de AWS: Scanning tables).

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

El truco está en esa línea de jq: tienes que escribir a mano .id.S, .name.S, .price.N — alcanzando más allá del descriptor de tipo de cada atributo (S, N, B, BOOL, M, L, SS, NS, BS) para obtener el valor en bruto. Eso es manejable para una tabla plana con tres columnas de texto. Se desmorona en cuanto tienes:

  • Mapas/listas anidados{"M": {...}} o {"L": [...]} no tienen una sola columna a la que aplanarse; @csv se atasca, o codificas la celda en JSON a mano.
  • Conjuntos{"SS": ["a","b"]} es un array, no un escalar.
  • Atributos dispersos — DynamoDB no tiene schema, así que el Item A puede tener un price y el Item B puede no tenerlo. Tu lista fija de columnas silenciosamente descarta o desalinea columnas.

Tampoco hay un --output csv que entienda los tipos de DynamoDB. La salida csv de la CLI aplana la respuesta en bruto, descriptores incluidos — así que aún necesitas jq (o un script) para quitar las etiquetas de tipo. Esa es la razón central por la que «exportar una tabla de DynamoDB a CSV con AWS CLI» nunca es de una sola línea más allá del caso trivial.

Para exportar una tabla más grande entera por esta vía sin que te lleve todo el día, paraleliza el scan con --segment / --total-segments (Docs de AWS: Parallel scan — DynamoDB «asigna los Items a segmentos aplicando una función hash a la clave de partición de cada Item», así que los segmentos pueden quedar desiguales), y lee paginación para no detenerte en la primera página de 1 MB.

Método 2: exportación de DynamoDB a S3 (tablas grandes)

Para tablas de cualquier tamaño real, la exportación gestionada a Amazon S3 es la herramienta correcta. Exporta una instantánea desde cualquier punto de tu ventana de recuperación a un instante en el tiempo (PITR) — así que PITR debe estar habilitado en la tabla primero — se ejecuta de forma asíncrona, y no consume unidades de capacidad de lectura, por lo que no tiene impacto en el rendimiento ni en la disponibilidad de tu tabla (Docs de AWS: «Las exportaciones son asíncronas, no consumen unidades de capacidad de lectura (RCU) y no tienen impacto en el rendimiento ni la disponibilidad de la tabla»; «Necesitas habilitar PITR en tu tabla para usar la funcionalidad de exportación»). Esto es también lo que la acción Exports to S3 de la consola dispara por debajo: la consola es solo un frontend para la misma API, así que conlleva el mismo requisito de PITR y la misma salida 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

El único inconveniente: la exportación a S3 no produce CSV. Escribe JSON de DynamoDB o Amazon Ion únicamente, como archivos gzip en formato JSON-lines (un Item por línea), más archivos de manifiesto (Docs de AWS: formato de salida de exportación — los archivos de datos se escriben como .json.gz, «el formato es JSON lines», junto con manifest-summary.json / manifest-files.json). Aún necesitas un paso de conversión después:

  • Athena / Glue leen el JSON de DynamoDB exportado directamente — apunta una tabla al prefijo de S3, y luego escribe CSV desde un SELECT (esta es la canalización habitual «exportar DynamoDB a S3 y luego a CSV»). AWS señala que «muchos servicios de AWS, como Athena y AWS Glue, analizarán este formato automáticamente» (formato de salida de exportación).
  • Hazlo tú mismo — descomprime los archivos .gz, analiza cada línea JSON y aplánala (el mismo problema de aplanado que cualquier otro método).

También es una instantánea de tabla completa: no hay filtro en el lado del servidor para exportar solo algunos Items. Si necesitas un subconjunto, o filtras después con Athena, o usas un script / GUI en su lugar.

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

Cuando necesitas un CSV con forma — columnas concretas, un subconjunto filtrado, manejo a medida de campos anidados — un pequeño script supera a pelearse con jq. La ventaja es que los SDK de AWS hacen el unmarshall del JSON tipado por ti: la interfaz de recursos de boto3 y el DynamoDBDocumentClient del SDK de JS devuelven {"price": 2000} simple en vez de {"price": {"N": "2000"}} (la interfaz de recursos de boto3 hace «el tipado de datos implícito», según la guía de Python de AWS; el DocumentClient de JS «convierte los datos de respuesta anotados a tipos nativos de JavaScript», según @aws-sdk/lib-dynamodb).

import boto3, csv

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

Aún te corresponden dos decisiones que el SDK no puede tomar por ti: cómo aplanar mapas/listas anidados en columnas (¿codificar la celda en JSON? ¿usar rutas con puntos para las claves?), y qué hacer con los atributos dispersos (aquí una clave ausente se vuelve una celda vacía vía r.get(k)). Y no descartes el bucle de LastEvaluatedKey — una sola llamada a scan() devuelve solo la primera página de 1 MB, así que sin él exportas silenciosamente parte de la tabla.

La misma advertencia que en el Método 1: un scan de tabla completa aquí aún consume capacidad de lectura y compite con el tráfico en vivo. Para una tabla grande, prefiere el Método 2 y reforma el volcado.

Método 4: exportación con un clic en DynoTable

Las rutas de script y CLI funcionan, pero reconstruyes la misma lógica de aplanado y paginación cada vez. DynoTable lo hace por ti: ejecuta o filtra una consulta, y luego exporta las filas visibles directamente a CSV (o Excel) — descriptores de tipo desenvueltos, mapas y listas anidados aplanados, conjuntos manejados, y solo los Items y columnas que realmente quieres en la salida.

Como exportas la vista actual, obtienes el CSV filtrado/con forma que la instantánea de tabla completa del Método 2 no puede darte — sin escribir un bucle de scan. Es un cliente de escritorio de DynamoDB, la misma herramienta que ya usas para explorar la tabla; mira cómo se compara con otras GUIs de DynamoDB.

Trampas: JSON de DynamoDB vs CSV plano

Sea cual sea el método que elijas, el mismo puñado de desajustes entre el modelo de datos de DynamoDB y un CSV plano te morderá:

  • Descriptores de tipo. La salida en bruto de API / CLI / exportación a S3 envuelve cada valor ({"S": "..."}, {"N": "123"}). O lo desenvuelves vía un SDK o quitas el descriptor tú mismo. El conjunto completo es S, N, B, BOOL, NULL, M, L, SS, NS, BS — mira tipos de datos de DynamoDB.
  • Mapas y listas anidados (M, L) pueden anidarse hasta 32 niveles de profundidad (Docs de AWS: tipos de datos — lista y mapa «pueden anidarse entre sí, para representar estructuras de datos complejas de hasta 32 niveles de profundidad») y no tienen forma natural de una sola columna. Decide de antemano: codifica la celda en JSON, o expande las claves anidadas en columnas con ruta de puntos (address.city).
  • Conjuntos (SS/NS/BS) son colecciones sin orden, no escalares — AWS advierte «el orden de los valores dentro de un conjunto no se preserva» (tipos de datos) — así que aplana a una cadena delimitada y no confíes en el orden de los elementos.
  • Atributos dispersos. DynamoDB no tiene schema, así que dos Items pueden tener atributos distintos. No hay un conjunto fijo de columnas; une las claves de todos los Items o las columnas se desalinearán. Esto es una consecuencia directa del diseño de tabla única, donde una tabla contiene varias formas de entidad.
  • Paginación. Scan (y Query) devuelven como máximo 1 MB por llamada. Si no haces el bucle sobre LastEvaluatedKey, exportarás silenciosamente solo la primera página. Mira paginación.
  • Precisión numérica. Los números de DynamoDB llevan hasta 38 dígitos de precisión y viajan como cadenas (Docs de AWS: tipos de datos: «Los números pueden tener hasta 38 dígitos de precisión»; «Todos los números se envían por la red a DynamoDB como cadenas»); el software de hojas de cálculo puede convertir números o IDs largos en floats y perder dígitos. Mantenlos como texto.

Preguntas frecuentes

¿Cómo exporto una tabla de DynamoDB a CSV con la AWS CLI? Haz un scan de la tabla y reforma la salida con jq (Método 1): aws dynamodb scanjq para quitar el descriptor de tipo de cada valor → @csv. No hay un --output csv consciente de DynamoDB, así que siempre haces el quitado de tipos tú mismo, y se rompe con mapas anidados, listas y conjuntos.

¿Puedo exportar una tabla de DynamoDB directamente a CSV desde AWS? No en un solo paso. La consola y la exportación gestionada a S3 producen ambas JSON de DynamoDB o Amazon Ion, nunca CSV. Siempre necesitas un paso de conversión — CLI + jq, un script, Athena/Glue sobre el volcado de S3, o una GUI que haga el aplanado por ti.

¿Cómo exporto una tabla de DynamoDB entera sin afectar a producción? Usa la función de exportación a S3 (Método 2). Se ejecuta de forma asíncrona y no consume unidades de capacidad de lectura, así que no compite con el tráfico en vivo — a diferencia de un Scan, que se mide contra el rendimiento de tu tabla (Docs de AWS). Requiere que PITR esté habilitado y exporta la tabla completa, no un subconjunto filtrado.

¿Cómo exporto DynamoDB a S3 como CSV? La exportación gestionada solo escribe JSON de DynamoDB / Ion en S3, así que «a CSV» es un segundo salto: registra el prefijo de exportación como una tabla de Athena (o Glue) y escribe CSV desde un SELECT. No hay un --export-format CSV.

¿Cómo exporto DynamoDB a Excel? Exporta a CSV primero (cualquier método de arriba), luego abre el CSV en Excel — manteniendo los IDs numéricos largos como texto para que no se conviertan en floats. No hay exportación directa a .xlsx desde DynamoDB; una GUI como DynoTable puede guardar la vista actual directamente a un CSV listo para hojas de cálculo.

¿Por qué mi JSON exportado tiene {"S": ...} y {"N": ...} por todas partes? Ese es el formato de cable marshalled de DynamoDB — cada valor está etiquetado con un descriptor de tipo. Hazle unmarshall con un SDK, el conversor de JSON de DynamoDB, o una GUI antes de escribir CSV. El formato de cable es el mismo tanto si los datos vienen de la API, la CLI o la exportación a S3.

Explora, filtra y exporta tus propias tablas a CSV con DynoTable, o desenvuelve una muestra de JSON de DynamoDB en el conversor de JSON primero.

Actualizado