Cómo aplanar JSON anidado a CSV: 5 estrategias y matriz de decisión
El problema de geometría
Siempre te topas con la misma pared. Una API devuelve JSON anidado y el analista en Slack solo quiere una hoja de cálculo. mongoexport produce envoltorios $oid y tres niveles de metadatos, y BigQuery espera una tabla plana. Aplanar JSON anidado a CSV no es un problema de sintaxis. Es un problema de geometría. JSON es un árbol, CSV es una cuadrícula, y no puedes meter un árbol en una cuadrícula sin elegir cómo se colapsan las ramas.
Existen exactamente cinco estrategias de colapso. Elige la equivocada y enviarás 200 columnas a Excel, perderás precisión en un ID de Twitter o romperás el ida y vuelta del que depende tu pipeline. Elige la correcta y la conversión se resuelve en una sola línea.
| Estrategia | Línea resumen | Mejor para |
|---|---|---|
| Notación de puntos | customer.address.city | Análisis en Excel/Sheets |
| Guion bajo | customer_address_city | Columnas amigables con SQL |
| Arrays indexados | items.0.sku, items.1.sku | Arrays de tamaño fijo |
| Explosión de filas | Repetir padre por cada hijo | Analítica en Pandas/BigQuery |
| Stringify | "{\"city\":\"Seattle\"}" en una celda | Ida y vuelta sin pérdida |
Esta guía recorre cada estrategia, te entrega una matriz de decisión indexada por consumidor (Excel, Pandas, BigQuery, Postgres) y muestra cuatro payloads reales donde la estrategia correcta no es la obvia. Si además necesitas la visión bidireccional general (bibliotecas de parsers, streaming, trampas de codificación), consulta la Guía de conversión CSV a JSON: Métodos, errores comunes.
Por qué el JSON anidado no encaja en CSV
JSON carga tres tipos de estructura que el CSV no tiene. Jerarquía es un objeto dentro de otro objeto. Secuencia es un array. Mixto es la combinación: arrays de objetos, objetos con arrays, arrays de arrays. Un pedido típico de comercio electrónico es las tres cosas a la vez.
CSV tiene exactamente dos dimensiones: filas y columnas. No existe un tercer eje para “esta columna contiene tres hijos”. Cuando exiges una cuadrícula a partir de un árbol, algo cede. O bien repartes los hijos en más columnas (y convives con nombres como items.0.options.0.value), o los repartes en más filas (los campos del padre se repiten), o los compactas en una sola celda como texto y dejas de tratarlos como estructura.
Cada estrategia que sigue responde esa pregunta de forma distinta. Algunas preservan la legibilidad y pierden la seguridad de ida y vuelta. Otras hacen lo contrario. Ninguna es universal. Ajusta la respuesta a quién leerá el archivo después.
Comparación de las 5 estrategias de aplanado
Estrategia 1: Notación de puntos (customer.address.city)
La notación de puntos camina desde la raíz hasta la hoja y usa . para unir las claves. Cada objeto anidado se convierte en una columna por hoja, con la ruta codificada en el nombre de la columna.
{ "customer": { "address": { "city": "Seattle" } }, "email": "alice@example.com" }
se convierte en
customer.address.city,email
Seattle,alice@example.com
En Pandas, una línea lo cubre:
import pandas as pd
data = [{"customer": {"address": {"city": "Seattle"}}, "email": "alice@example.com"}]
df = pd.json_normalize(data, sep='.')
df.to_csv("out.csv", index=False)
En JavaScript, basta con una pequeña función recursiva:
function flattenDot(obj, prefix = '', acc = {}) {
for (const [k, v] of Object.entries(obj)) {
const key = prefix ? `${prefix}.${k}` : k;
if (v && typeof v === 'object' && !Array.isArray(v)) {
flattenDot(v, key, acc);
} else {
acc[key] = v;
}
}
return acc;
}
Pros: legible para humanos, valor por defecto en Pandas, preserva la ruta original. Contras: los nombres de columna pueden volverse largos (las specs de Kubernetes producen nombres como spec.template.spec.containers.0.resources.limits.memory), y el punto se vuelve ambiguo si una clave real contiene . (los parámetros de evento de Google Analytics 4 los tienen).
Estrategia 2: Notación con guion bajo (customer_address_city)
Misma idea, separador distinto. Reemplaza . por _ y el resultado es seguro para SQL: SELECT customer_address_city FROM events funciona sin entrecomillar el identificador. BigQuery, Snowflake y Postgres prefieren todos esta opción.
import pandas as pd
df = pd.json_normalize(data, sep='_')
La decisión entre punto y guion bajo se reduce puramente a la herramienta de destino. Los analistas de Excel leen el punto con más naturalidad; los motores SQL aceptan el guion bajo sin quejarse. Se cambia modificando un solo argumento.
Pros: nombres de columna seguros para SQL, identificadores conformes con BigQuery, no requiere entrecomillado. Contras: la ambigüedad persiste si una clave contiene _ (menos común que . pero aún posible).
Estrategia 3: Arrays indexados (items.0.sku, items.1.sku)
Los objetos se aplanan limpiamente porque las claves son únicas. Los arrays no, porque la longitud no tiene cota. La estrategia indexada trata las posiciones del array como segmentos de ruta: items[0] se convierte en items.0.
{ "id": "ord-001", "items": [{"sku": "A"}, {"sku": "B"}] }
se convierte en
id,items.0.sku,items.1.sku
ord-001,A,B
Este es el comportamiento Flatten por defecto en nuestro Convertidor JSON a CSV. Cada hoja recibe su propia columna; la posición queda registrada en el nombre.
Pros: cada valor obtiene su propia celda, la posición se preserva, sin duplicación de filas. Contras: la cantidad de columnas explota (100 elementos = 100 columnas); las filas con arrays de distinta longitud producen tablas dentadas; la agregación posterior se rompe (no hay SUM(items.*.qty)).
Estrategia 4: Explosión de filas (array a múltiples filas)
En lugar de ensanchar la tabla para que quepa el array, alárgala. Repite los campos del padre una vez por cada elemento del array, y deja que cada elemento se convierta en su propia fila.
{ "order_id": "ord-001", "customer": "Alice", "items": [{"sku": "A", "qty": 2}, {"sku": "B", "qty": 1}] }
se convierte en
order_id,customer,items.sku,items.qty
ord-001,Alice,A,2
ord-001,Alice,B,1
En Pandas, una línea hace tanto la explosión como la normalización:
import pandas as pd
orders = [{"order_id": "ord-001", "customer": "Alice",
"items": [{"sku": "A", "qty": 2}, {"sku": "B", "qty": 1}]}]
df = pd.json_normalize(orders, record_path='items', meta=['order_id', 'customer'])
df.to_csv("orders.csv", index=False)
En SQL, UNNEST hace lo mismo:
SELECT order_id, item.sku, item.qty FROM orders, UNNEST(items) AS item;
Pros: Pandas y BigQuery tratan esta forma de manera nativa, las agregaciones funcionan (GROUP BY order_id), el esquema se mantiene estrecho. Contras: los campos del padre se duplican en cada fila hija (inflación de almacenamiento), la frontera 1-a-muchos es implícita (necesitas un order_id), y dos arrays en el mismo nivel producen un producto cartesiano salvo que los hagas UNNEST con cuidado.
Estrategia 5: Stringify (JSON dentro de la celda)
No aplanes nada. Serializa el valor anidado completo como cadena JSON y colócalo en una única celda. La tabla externa se mantiene plana; la estructura queda preservada literalmente en el interior.
{ "id": "ord-001", "items": [{"sku": "A"}, {"sku": "B"}] }
se convierte en
id,items
ord-001,"[{""sku"":""A""},{""sku"":""B""}]"
Este es el modo Stringify en nuestro Convertidor JSON a CSV. La cantidad de columnas nunca explota, la forma original se preserva byte a byte y el viaje inverso reconstruye la entrada exactamente.
Pros: 100% sin pérdida, cantidad de columnas predecible, ida y vuelta seguro cuando se combina con Infer types en sentido inverso. Contras: los usuarios de Excel ven comillas escapadas, los motores SQL necesitan funciones JSON para consultar dentro del valor (JSON_EXTRACT_SCALAR en BigQuery, ->>'key' en Postgres) y las fórmulas de hoja de cálculo no pueden alcanzar el interior de la celda.
Las 5 estrategias lado a lado
Misma entrada en las cinco: {"id":"ord-001","customer":{"name":"Alice"},"items":[{"sku":"A","qty":2},{"sku":"B","qty":1}]}.
| Estrategia | Columnas | Ida y vuelta seguro | Mejor consumidor |
|---|---|---|---|
| Notación de puntos | crece con el array | No | Analista de Excel |
| Guion bajo | crece con el array | No | Almacén SQL |
| Arrays indexados | 2 por posición de array | No (ambiguo en inverso) | Arrays de tamaño fijo |
| Explosión de filas | estrecha, 1 fila por hijo | Parcial (necesita clave) | Pandas / BigQuery |
| Stringify | fija | Sí | Ida y vuelta del pipeline |
Matriz de decisión: qué estrategia para qué consumidor
Busca primero el consumidor, luego lee la estrategia recomendada.
| Consumidor | Estrategia recomendada | Por qué |
|---|---|---|
| Excel / Sheets (analista) | Puntos + Stringify para arrays grandes | Nombres de columna legibles; los arrays grandes no inflan la hoja |
| Excel-EU (DE/FR/IT/ES) | Puntos + delimitador ; + BOM UTF-8 | Punto y coma requerido; el BOM evita la corrupción de codificación |
Pandas (json_normalize + explode) | Guion bajo + Explosión de filas | Columnas amigables con SQL; explode combina bien con groupby |
| BigQuery / Snowflake | TSV + Stringify o Explode | El tab evita las trampas de comillas; JSON_EXTRACT consulta la celda |
COPY de PostgreSQL | RFC 4180 + Guion bajo + plano | Columnas seguras para SQL; entrecomillado RFC estricto |
| ETL MongoDB → BigQuery | Cargar NDJSON directo, omitir CSV | BigQuery carga NDJSON de forma nativa; el CSV es un rodeo |
Excel / Google Sheets: la trampa del locale
Los nombres de columna en Excel no tienen un límite práctico de longitud. Las trampas reales son tres.
Primero, la división por locale. El Excel europeo (Alemania, Francia, Italia, España) espera ; como delimitador porque , es el separador decimal. Un CSV separado por comas se abre con cada fila colapsada en la columna A. El preset Excel en nuestra herramienta Convertidor JSON a CSV cambia a ; + CRLF + BOM UTF-8 con un clic.
Segundo, la notación científica. Excel ve 9007199254740993 y muestra 9.00719925474E+15. Almacena los enteros grandes como cadenas en el JSON de origen y activa el BOM para que Excel mantenga la celda como texto. Nuestro convertidor detecta los enteros grandes automáticamente.
Tercero, el límite práctico de columnas. Excel teóricamente soporta 16,384 columnas, pero cualquier cosa por encima de ~500 se vuelve inmanejable. Stringifica los sub-árboles pesados o pre-proyecta con jq antes de convertir.
Pandas: json_normalize + explode
El patrón estándar para arrays anidados es record_path + meta en una sola pasada:
import pandas as pd
orders = [{
"order_id": "ord-001",
"customer": {"name": "Alice", "city": "Seattle"},
"items": [{"sku": "SKU-100", "qty": 2}, {"sku": "SKU-205", "qty": 1}]
}]
df = pd.json_normalize(orders, record_path='items',
meta=['order_id', ['customer', 'name'], ['customer', 'city']], sep='_')
df.to_csv("orders.csv", index=False)
La salida es una fila por elemento con order_id, customer_name y customer_city repetidos. Esto supera a ejecutar explode primero y json_normalize después: record_path se salta la columna de objeto intermedia y meta te permite controlar qué campos del padre se propagan. Para entradas donde los elementos del array contienen objetos anidados, define max_level= para acotar la profundidad.
BigQuery / Snowflake: TSV + JSON dentro de la celda
El LOAD DATA de BigQuery es estricto con el entrecomillado CSV y a menudo parsea mal archivos con comas dentro de texto entrecomillado. TSV es más seguro porque los tabs casi nunca aparecen dentro de campos de texto:
bq load --source_format=CSV --field_delimiter='\t' \
dataset.orders gs://bucket/orders.tsv \
order_id:STRING,customer:STRING,items:STRING
Cuando cargas datos anidados como JSON serializado en una sola columna, BigQuery todavía consulta dentro con JSON_EXTRACT_SCALAR:
SELECT order_id, JSON_EXTRACT_SCALAR(items, '$[0].sku') AS first_sku
FROM dataset.orders;
Snowflake provee la misma capacidad mediante VARIANT, con consultas de ruta como items:0.sku::STRING. En ambos motores, Stringify + consultas con rutas JSON superan al aplanado completo cuando los arrays anidados son grandes o de longitud variable.
COPY de PostgreSQL: RFC 4180 estricto
COPY ... FROM ... WITH (FORMAT csv, HEADER true) es el lector de RFC 4180 más estricto que te vas a encontrar comúnmente. Dos comportamientos hacen tropezar a la gente.
Primero, COPY no acepta un BOM UTF-8. La marca de orden de bytes se convierte en un prefijo literal en el nombre de la primera columna (id en vez de id), y cada consulta que referencie id falla en silencio. Apaga el BOM para destinos Postgres.
Segundo, COPY no puede parsear datos anidados de forma nativa. O explota los arrays en múltiples filas antes de cargar, o define el destino como jsonb y stringifica el valor anidado:
CREATE TABLE orders (order_id text PRIMARY KEY, customer text, items jsonb);
COPY orders FROM '/tmp/orders.csv' WITH (FORMAT csv, HEADER true);
SELECT order_id, items->0->>'sku' AS first_sku FROM orders;
Para pipelines que ya hablan JSON de extremo a extremo, omite el CSV y usa COPY ... FROM ... WITH (FORMAT text) con entrada JSON-line.
Recorridos con payloads del mundo real
Recorrido 1: Pedidos de comercio electrónico (cliente + array de items)
Un pedido típico combina información de cliente anidada con un array de items de longitud variable:
[{ "id": "ord-001",
"customer": { "name": "Alice", "address": {"city": "Seattle", "country": "US"} },
"items": [{"sku": "SKU-100", "qty": 2}, {"sku": "SKU-205", "qty": 1}] }]
La estrategia correcta depende de quién lee el archivo. Finanzas quiere una fila por elemento para calcular ingresos por SKU; esa es la estrategia de explosión, que produce dos filas con id y customer.name repetidos. Operaciones quiere una fila por pedido para los dashboards de cumplimiento; esa es la notación de puntos con items stringificado para que el array no infle la cantidad de columnas. Misma entrada, dos salidas, ambas correctas para su consumidor.
Pega el payload en nuestro Convertidor JSON a CSV y alterna Flatten contra Stringify en la opción Nested. El ejemplo “Nested E-commerce Orders” carga la misma forma.
Recorrido 2: API de Issues de GitHub (array de labels + objeto user)
El endpoint /repos/{owner}/{repo}/issues devuelve una forma anidada mixta:
[{ "id": 1001, "title": "Bug: login 404", "state": "open",
"labels": ["bug", "priority:high"], "user": {"login": "alice"} }]
user es un objeto con un solo campo útil; labels es un array de strings de longitud no acotada. El aplanado pragmático es híbrido: notación de puntos sobre user (solo te importa user.login) y unión en línea sobre labels en una sola celda separada por ;:
id,title,state,labels,user.login
1001,Bug: login 404,open,bug;priority:high,alice
No puedes capturar simultáneamente “unir arrays en una celda” y “aplanar objetos con puntos” en una sola estrategia. Nuestro convertidor maneja el aplanado de objetos automáticamente; pre-procesa las labels con jq (map(.labels = (.labels | join(";")))) o acepta el comportamiento por defecto de stringificar arrays.
Recorrido 3: mongoexport de MongoDB ($oid + metadatos)
mongoexport --jsonArray produce envoltorios de Extended JSON:
[{ "_id": {"$oid": "6634a1b2c3d4e5f600000001"},
"email": "alice@example.com",
"metadata": { "signupDate": "2026-01-15T10:30:00Z",
"preferences": {"newsletter": true, "theme": "dark"} } }]
El envoltorio $oid produce una columna literalmente llamada _id.$oid, que la mayoría de los motores SQL rechazan. Pre-procesa con jq para desenvolverlo:
mongoexport --collection=users --jsonArray | jq 'map(._id = ._id."$oid")' > users.json
Para el bloque profundamente anidado metadata.preferences, elige según el consumidor. Exportación para analista: aplana con puntos todo el conjunto; metadata.preferences.theme se lee bien. Ida y vuelta de pipeline: stringifica metadata para mantener la estructura intacta. Para patrones completos de jq que se combinan con pipelines CSV, consulta nuestro jq Cheat Sheet.
Recorrido 4: Pod Spec de Kubernetes (profundamente anidado)
Una respuesta de kubectl get pod -o json es el peor caso para las estrategias planas. La estructura rutinariamente llega a seis niveles de profundidad (spec.template.spec.containers.0.resources.limits.memory). El aplanado ingenuo con puntos produce nombres de columna que superan los 70 caracteres y más de 200 columnas de salida. Funcionan dos estrategias.
Pre-proyectar con kubectl jsonpath. Elige solo los campos que realmente necesitas:
kubectl get pods -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\t"}{.status.phase}{"\n"}{end}' > pods.tsv
Stringificar el spec, aplanar los metadatos. Mantén metadata (name, namespace, labels) plano y stringifica spec en una sola celda:
kubectl get pods -o json | jq 'map({name: .metadata.name, namespace: .metadata.namespace, spec: (.spec | tostring)})'
Luego pega en el convertidor con el modo Flatten. La columna spec se convierte en una celda JSON; las columnas de metadatos quedan legibles. Evita el antipatrón kubectl get pod -o json | json-to-csv flatten sin pre-proyección. La cantidad de columnas será inmanejable.
Seguridad del ida y vuelta: aplanar pierde datos, Stringify es sin pérdida
Un teorema que las guías de la competencia se saltan. La notación de puntos, la notación con guion bajo, los arrays indexados y la explosión de filas son todos proyecciones de una sola dirección. Una vez que aplanas con cualquiera de ellos, el JSON original no se puede reconstruir perfectamente solo a partir del CSV.
Los contraejemplos son fáciles de construir. Una columna llamada customer.address.city es ambigua entre {"customer": {"address": {"city": "..."}}} y {"customer": {"address.city": "..."}}. Los arrays indexados parecen reversibles, pero el CSV no puede decir si items.0.sku debería reconstruirse como un array o como un objeto con clave numérica. La explosión de filas requiere una clave de agrupación; sin order_id, no puedes saber qué filas pertenecían al mismo padre.
Solo Stringify sobrevive al ida y vuelta. El valor anidado se preserva literalmente como cadena JSON, así que el convertidor inverso lee la celda, la parsea y reinserta el original intacto. Convierte con Stringify, guarda el CSV, pega en nuestro Convertidor CSV a JSON, activa Infer types y obtendrás bytes idénticos a la entrada.
La regla práctica: ida y vuelta de pipeline → Stringify. Análisis o reporte de una sola vez → puntos, guion bajo o explosión según el consumidor.
Hacerlo en nuestra herramienta de navegador
El Convertidor JSON a CSV expone dos de las cinco estrategias directamente: Flatten (que combina notación de puntos y arrays indexados) y Stringify (que preserva la estructura dentro de una celda). Las otras tres (guion bajo, explosión de filas, presets para destinos SQL) están a un paso de pre-procesado de distancia.
Una sesión típica lleva cinco clics:
- Valida la entrada con nuestro Formateador JSON para que los errores de sintaxis no se conviertan en fallas silenciosas de conversión.
- Pega el JSON en el Convertidor JSON a CSV. La conversión corre al instante.
- Pon Nested en Flatten para claves con puntos e indexadas, o Stringify para mantener arrays y objetos en celdas individuales.
- Elige un preset: RFC 4180 para pipelines, Excel para hojas de cálculo de la UE, TSV para almacenes, Pipe para texto con muchas comas.
- Haz clic en Swap direction y usa el Convertidor CSV a JSON con Infer types activado para verificar un ida y vuelta con Stringify.
Todo corre en tu navegador. PII, exportaciones internas y secretos de producción nunca salen de la página; hay cero solicitudes de red después de cargar la página. Seguro para datos sensibles donde subir a un sitio de terceros no es una opción.
Trampas comunes
Seis modos de falla recurrentes.
- Explosión de nombres de columna. Las specs de Kubernetes y los hilos de revisión de PR de GitHub producen cientos de rutas hoja. Solución: pre-proyecta con
jqokubectl jsonpath, o stringifica los sub-árboles pesados mientras aplanas los metadatos. - Desajuste de longitud de array. La fila 1 tiene 3 elementos, la fila 2 tiene 5. Los arrays indexados producen celdas en blanco en
items.3.skuyitems.4.skupara la fila 1. Solución: cambia a explosión de filas. - Claves índice tratadas como cadenas en el inverso. Cuando CSV-a-JSON ve
items.0.sku, el0es técnicamente una clave de tipo cadena. Algunos convertidores inversos reconstruyen{"0": {"sku": "A"}}en vez de[{"sku": "A"}]. Solución: usa Stringify para los ida y vueltas. - Claves que ya contienen el separador. Los eventos de GA4 tienen claves como
event_params.keyque contienen puntos literales; aplanar con.produce rutas ambiguas. Solución: usa guion bajo, o renombra las claves problemáticas. Consulta nuestra Guía De JSON5 a JSONC para contexto sobre formatos JSON con soporte extendido de claves. - Tipos en niveles mixtos. Algunas filas tienen
addresscomo objeto, otras comonull. El aplanado produce celdas vacías donde el objeto era nulo. La advertencia de notas de esquema en nuestro convertidor lo marca para que puedas verificar al consumidor posterior. - Enteros grandes truncados por Excel. Un
$oidLong, un ID snowflake de Twitter o unresourceVersionde K8s excede el rango seguro de JavaScript (2^53 - 1) y se redondea en silencio. Excel luego los muestra como9.00719925474E+15. Solución: almacena los IDs como cadenas en el JSON de origen, habilita el BOM y usa el preset Excel.
Preguntas frecuentes
¿Cuál es la mejor forma de aplanar JSON anidado a CSV?
La mejor forma de aplanar JSON anidado a CSV depende del consumidor posterior. Usa notación de puntos para Excel o Google Sheets. Usa explosión de filas cuando Pandas o BigQuery vayan a agregar los datos. Usa Stringify cuando el CSV deba volver a JSON sin pérdida de datos. Adapta la estrategia al siguiente lector.
¿Cómo convierto un array JSON en múltiples filas CSV?
Convierte un array JSON en múltiples filas CSV usando la estrategia de explosión: duplica los campos del padre una vez por cada elemento del array para que cada uno se vuelva su propia fila. En Pandas, pd.json_normalize(data, record_path='items', meta=['order_id']) lo hace en una sola llamada. En SQL, UNNEST(items) produce la misma forma. Las claves del padre se repiten en las filas explotadas.
¿Puedo hacer ida y vuelta del CSV al JSON anidado original?
El ida y vuelta del CSV al JSON anidado original solo funciona con el modo Stringify. La notación de puntos, el guion bajo, los arrays indexados y la explosión de filas son proyecciones de una sola dirección con pérdida; el convertidor inverso no puede reconstruir el árbol perfectamente. Stringify preserva arrays y objetos como JSON dentro de una sola celda, así que el ida y vuelta completo es byte a byte idéntico cuando Infer types está activado.
¿Por qué Excel muestra mi JSON aplanado como una sola columna larga?
Excel muestra tu JSON aplanado como una sola columna larga cuando estás en un locale europeo (Alemania, Francia, Italia, España) donde la coma está reservada para los decimales y Excel espera punto y coma como delimitador. El preset Excel en Convertidor JSON a CSV cambia a ; + CRLF + BOM UTF-8 con un clic.
¿Debo usar notación de puntos o guion bajo para los nombres de columna?
Usa notación de puntos cuando el destino es Excel, Google Sheets o Pandas; los puntos son el valor por defecto de json_normalize y se leen con naturalidad. Usa guion bajo cuando el destino es SQL: Postgres, BigQuery y Snowflake requieren entrecomillado alrededor de identificadores que contengan puntos, mientras que los guiones bajos se aceptan sin comillas en todas partes.
¿Cómo maneja pandas json_normalize los arrays de objetos?
json_normalize de Pandas maneja los arrays de objetos mediante los argumentos record_path y meta. pd.json_normalize(data, record_path='items', meta=['order_id']) explota items en una fila por elemento con order_id repetido. Para objetos anidados sin arrays, el más simple pd.json_normalize(data, sep='_') produce nombres de columna separados por guion bajo como customer_address_city. Usa max_level= para acotar la profundidad en árboles profundos.
¿Cuál es el límite de columnas al aplanar JSON profundamente anidado?
El límite de columnas al aplanar JSON profundamente anidado es 16,384 en Excel y prácticamente sin cota en el propio CSV, pero pasadas las 500 columnas la salida se vuelve inmanejable. Las specs de Pods de Kubernetes o las respuestas de GraphQL las exceden fácilmente. Stringifica los sub-árboles pesados con el Convertidor JSON a CSV o pre-proyecta con jq o kubectl jsonpath.
¿Es jq una buena herramienta para aplanar JSON antes de la conversión a CSV?
Sí, jq es la herramienta correcta para aplanar JSON antes de la conversión a CSV. Maneja la pre-proyección (map({id, name})), la pre-explosión (.[] | {id, item: .items[]}) y la normalización de forma en una sola línea. El pipeline de jq corre antes del paso CSV y controla exactamente qué campos llegan al convertidor. Consulta nuestro jq Cheat Sheet para ver patrones.
Conclusión
Cinco ideas clave:
- JSON a CSV es un problema de geometría, no de sintaxis. Un árbol no entra en una cuadrícula sin elegir cómo se colapsan las ramas.
- Cinco estrategias cubren el universo práctico (puntos, guion bajo, arrays indexados, explosión de filas, Stringify). Elige según el consumidor.
- Stringify es la única ruta sin pérdida. Úsala para los ida y vueltas de pipeline.
- Excel-EU y BigQuery tienen presets por una razón. Úsalos.
- Los payloads reales (mongoexport, specs de Kubernetes, respuestas de GitHub) suelen necesitar primero un paso de pre-proyección con
jqokubectl jsonpath.
Prueba tu propio payload en el Convertidor JSON a CSV. Corre localmente, maneja las cinco estrategias, hace ida y vuelta sin pérdida con Stringify. Sin subida, sin registro, los datos nunca salen de la página.