Guide
CSV a JSON: cuándo la conversión corrompe datos
La conversión en sí es trivial. La corrupción ocurre en las dos preguntas que todo conversor responde en silencio: ¿dónde termina este campo? y ¿de qué tipo es este valor?
By Buğra SözeriPublished
Convertir CSV a JSON parece el trabajo más fácil de la plomería de datos: filas que entran, objetos que salen. También es una de las formas más confiables de corromper un conjunto de datos sin un solo mensaje de error. La corrupción nunca viene del paso de conversión en sí — viene de dos preguntas que todo conversor tiene que responder, normalmente en silencio: dónde termina este campo, y de qué tipo es este valor.
CSV parece simple. No lo es.
JSON tiene una gramática real (ECMA-404). CSV tiene RFC 4180, que es menos una especificación que una descripción del comportamiento común — y muchos archivos reales ignoran incluso eso. Las reglas del RFC que el código ingenuo se equivoca:
- Los campos pueden ir entre comillas, y un campo entre comillas puede contener comas, así que
"Smith, John"es un solo campo. Dividir una línea por comas está mal en el momento en que cualquier campo va entre comillas. - Las comillas se escapan duplicándolas:
"5'10"""codifica5'10". El escapado con barra invertida, que muchos analizadores hechos a mano asumen, no es RFC 4180. - Los campos entre comillas pueden contener saltos de línea. Una dirección de varias líneas es CSV válido, lo que significa que ni siquiera puedes leer un archivo CSV línea por línea. Esta única regla es por qué un analizador correcto debe tener estado.
Luego la realidad añade lo que el RFC no cubre: archivos «delimitados» por punto y coma o tabulaciones (configuraciones regionales europeas, donde la coma es el separador decimal), una marca de orden de bytes UTF-8 que pega silenciosamente tres bytes invisibles al primer nombre de encabezado (así que tu código busca id y la clave en realidad es id), y codificaciones heredadas como Windows-1252 que convierten cada nombre con acento en texto corrupto al leerse como UTF-8. Un conversor que no detecta el delimitador, no quita el BOM y no acierta la codificación corrompe el archivo antes de que empiece siquiera el manejo de tipos.
Detección de encabezado
RFC 4180 hace que la fila de encabezado sea opcional, y nada en el archivo dice si está presente. Adivina mal en una dirección y tu primer registro de datos se convierte en los nombres de clave para todo lo demás; adivina mal en la otra y obtienes claves como field1. Los buenos conversores usan una heurística — una primera fila que son todas cadenas no numéricas y no repetidas probablemente sea un encabezado — pero las heurísticas fallan con datos totalmente textuales, así que cualquier conversor que valga la pena te deja anular la suposición. Vigila también los nombres de encabezado duplicados: las claves de objeto JSON deben ser únicas, así que dos columnas amount significan que una gana silenciosamente o se renombra.
El problema de los tipos: todo es una cadena
CSV no tiene tipos. 42, TRUE y 2024-01-05 son todas simples secuencias de caracteres, y el conversor tiene que decidir en qué se convierten en JSON. Cada elección pierde algo:
- Ceros a la izquierda. Infiere
02134como un número y el código postal se convierte en2134. Lo mismo pasa con números de teléfono, códigos de producto y códigos bancarios: identificadores que parecen numéricos no son números. - Enteros grandes. La gramática de JSON permite números de cualquier tamaño, pero JavaScript (y la mayoría de los analizadores JSON) los almacenan como dobles IEEE 754, exactos solo hasta 253 − 1. Un ID de base de datos de 19 dígitos o un número del largo de una tarjeta de crédito se redondea a un valor cercano — en silencio. Los ID pertenecen en cadenas.
- Booleanos. ¿Es
TRUEel valor JSONtrueo la cadena que escribió un usuario? ¿YYes,Y,1? No hay una respuesta correcta, solo una documentada. - Fechas. JSON no tiene ningún tipo de fecha, y
03/04/2024es 4 de marzo o 3 de abril según la configuración regional. Mantener las fechas como cadenas es la única opción segura por defecto. - Campos vacíos. CSV no puede distinguir
nullde una cadena vacía de un valor ausente; JSON distingue los tres.
Excel merece su propia advertencia aquí, porque gran parte de la corrupción de CSV ocurre antes de que cualquier conversor vea el archivo. Excel aplica una inferencia de tipos agresiva al abrir: los ceros a la izquierda se eliminan, los enteros de más de 15 dígitos se redondean, y las cadenas parecidas a fechas se convierten — incluyendo, famosamente, nombres de genes humanos como MARCH1 y SEPT2, que aparecieron como fechas en miles de artículos de genética publicados hasta que los genes se renombraron oficialmente en 2020. Si un CSV alguna vez se abrió en Excel y se guardó, trata como sospechoso cualquier identificador con apariencia numérica que contenga.
La regla conservadora: deja que el conversor infiera tipos para medidas obvias, pero mantén como cadenas cualquier cosa que funcione como identificador — códigos postales, ID, números de cuenta — y verifica el resultado antes de confiarlo.
Filas planas vs JSON anidado
Una fila de CSV es plana; un objeto JSON no tiene por qué serlo. Cuando la forma objetivo está anidada, el anidamiento debe codificarse en los nombres de columna, y la convención de facto son los encabezados de ruta: una columna llamada user.address.city (notación con punto) o user[address][city] (notación con corchetes) se expande en objetos anidados, y items[0].sku, items[1].sku en un array de objetos. Muchos conversores y librerías soportan esta expansión; nada de esto está estandarizado, así que los puntos que son literalmente parte de un nombre de columna (price.usd como una clave plana) se expandirán mal a menos que la herramienta te deje desactivar la expansión. Elige una convención, aplícala en ambas direcciones, y documéntala.
Volviendo atrás: JSON a CSV pierde más
La conversión inversa pierde más. Un array uniforme de objetos planos se mapea limpiamente sobre una tabla; cualquier otra cosa fuerza decisiones. Los objetos anidados se aplanan en columnas de ruta. Los arrays son peores: un pedido con tres líneas o bien explota en tres filas (duplicando los campos del pedido y cambiando el número de filas) o se serializa como una cadena JSON dentro de una celda CSV — técnicamente válido, prácticamente ilegible en una hoja de cálculo. Los registros con distintas claves se unen en una tabla ancha y dispersa donde null, la cadena vacía, y la «clave ausente» colapsan todas en la misma celda vacía. Si tus datos sobreviven CSV→JSON→CSV de forma idéntica byte a byte, eran genuinamente tabulares; si no, la diferencia te muestra exactamente qué estructura no puede transportar CSV. Inspeccionar el JSON intermedio en un formateador antes de volver a convertir hace visibles esas pérdidas en lugar de silenciosas.
Cuándo JSONL supera a un array JSON
Una conversión convencional envuelve cada objeto-fila en un único array JSON grande — lo que significa que un consumidor debe analizar todo el archivo antes de tocar el primer registro, y un productor debe retenerlo todo para escribir el corchete de cierre. JSON Lines (JSONL/NDJSON) elimina el array: un objeto JSON completo por línea, separado por saltos de línea. Cada línea se analiza de forma independiente, así que el formato fluye, añade, divide y se puede buscar con grep como CSV mientras conserva los tipos y el anidamiento de JSON. Es el formato masivo nativo de herramientas como BigQuery y Elasticsearch, y el objetivo correcto siempre que el número de filas sea grande o no acotado. Regla general: array JSON para una carga del tamaño de una configuración que una API devuelve entera; JSONL para conjuntos de datos.
Tamaño y streaming
JSON repite cada nombre de clave en cada registro, así que la salida convertida suele ocupar de dos a cuatro veces el tamaño del CSV de origen — algo a tener en cuenta antes de convertir una exportación de varios gigabytes. Por el contrario, la regla de salto de línea entre comillas de CSV significa que el streaming correcto todavía requiere un analizador con estado, no un divisor de líneas. Para archivos de hasta decenas de megabytes, un conversor en el navegador maneja todo el trabajo localmente; más allá de eso, procesa por streaming con una librería (el módulo csv de Python, PapaParse y sus equivalentes analizan todos de forma incremental) y emite JSONL para que ninguna de las partes necesite el conjunto de datos en memoria. Y si los datos van rumbo a un archivo de configuración en lugar de a una canalización de datos, JSON puede no ser la última parada de todos modos — consulta nuestra comparación de JSON y YAML para configuración.
Versión corta: analiza el CSV con un analizador real, nunca con una división por comas; quita el BOM y confirma el delimitador y la codificación; trata los identificadores como cadenas por más numéricos que parezcan; nunca hagas pasar archivos de datos ida y vuelta por Excel; codifica el anidamiento con una convención de ruta documentada; y recurre a JSONL en el momento en que los datos dejen de caber cómodamente en memoria.
Frequently asked questions
- ¿Cómo convierto CSV a JSON?
- Analiza el CSV con un analizador real conforme a RFC 4180 (nunca una división ingenua por comas), trata la primera fila como nombres de campo y emite un objeto JSON por fila de datos con esos nombres como claves. Un conversor del lado del cliente hace esto en el navegador sin subir el archivo; para código, usa una librería CSV establecida en tu lenguaje en lugar de programar a mano las reglas de comillas. Las dos decisiones que hay que tomar deliberadamente son el manejo del encabezado y si se infieren tipos o se mantiene todo como cadenas.
- ¿Por qué falla dividir una línea de CSV por comas?
- Porque RFC 4180 permite que los campos vayan entre comillas, y un campo entre comillas puede contener comas, comillas dobles (escapadas duplicándolas) e incluso saltos de línea. Un valor como "Smith, John" es un solo campo, no dos, y una dirección entre comillas puede legalmente ocupar varias líneas. Dividir por comas — o leer línea por línea — interpreta mal todo esto. Cualquier conversor correcto usa un analizador con estado que rastrea si está dentro de comillas.
- ¿Por qué Excel cambia mis valores de CSV?
- Excel aplica inferencia de tipos al abrir: quita los ceros a la izquierda de cualquier cosa que parezca un número (códigos postales, números de teléfono, códigos de producto), redondea enteros de más de 15 dígitos para que quepan en sus celdas de punto flotante, y reinterpreta cadenas parecidas a fechas — la razón por la que miles de artículos de genética contenían nombres de genes como MARCH1 convertidos en fechas, hasta que los genes se renombraron en 2020. El daño ocurre al abrir y se guarda de vuelta si vuelves a exportar. Importa el CSV mediante el diálogo de importación de datos de Excel con las columnas configuradas como Texto, o evita por completo hacer pasar archivos de datos por Excel.
- ¿Cómo convierto CSV a JSON con objetos anidados?
- CSV es plano, así que el anidamiento debe codificarse en los nombres de columna. La convención habitual son rutas con punto o corchetes: columnas llamadas user.name y user.address.city (o user[address][city]) se expanden en objetos anidados, e items[0], items[1] en arrays. Los conversores y librerías que soportan «expansión de encabezados por ruta» aplican esto automáticamente; sin ello, obtienes un objeto plano por fila y debes reestructurar en código después. No hay un estándar — elige una convención y úsala de forma consistente en ambas direcciones.
- ¿Cuándo debería usar JSON en lugar de CSV, y viceversa?
- Usa CSV cuando los datos son genuinamente tabulares (las mismas columnas en cada fila, valores escalares), necesitan abrirse en hojas de cálculo, o son lo bastante grandes como para que la repetición de nombres de clave de JSON perjudique. Usa JSON cuando los registros están anidados, los campos varían entre registros, o los tipos importan — CSV no tiene tipos, así que los números, booleanos y nulos solo sobreviven en JSON. Para flujos de registros grandes, JSON Lines (un objeto por línea) combina los tipos de JSON con el procesamiento línea a línea de CSV.
- ¿Qué datos se pierden al convertir JSON a CSV?
- Cualquier cosa que no sea una tabla plana de escalares. Los objetos anidados deben aplanarse en columnas con nombre de ruta; los arrays de objetos o bien explotan en varias filas o se serializan como cadenas dentro de una celda CSV; la distinción entre null, cadena vacía y clave ausente colapsa, porque CSV representa las tres como un campo vacío; y cada anotación de tipo desaparece, ya que los valores de CSV son solo texto. Si el JSON es un array uniforme de objetos planos, la conversión no pierde nada — de lo contrario, espera tener que tomar (y documentar) decisiones de aplanamiento.
Sources & references
Authoritative references cited by this piece. Verified by Buğra Sözeri on the dates shown and re-checked at every deploy.
- RFC 4180 — Common Format and MIME Type for CSV Files — Lo más cercano a una especificación que tiene CSV: comillas, comas y saltos de línea incrustados, y la fila de encabezado opcional(as of )
- ECMA-404 — The JSON Data Interchange Syntax — La gramática de JSON, incluida la sintaxis numérica sin límite de precisión — los límites de precisión vienen de las implementaciones(as of )
- MDN — JSON.parse() and number precision — Documenta que JavaScript analiza los números JSON como dobles IEEE 754, perdiendo precisión entera más allá de 2^53(as of )
- JSON Lines specification — El formato de un valor JSON por línea, tratado como la alternativa amigable con el streaming frente a un único array JSON(as of )
Related
Published July 15, 2026