JSON_PRETTY

La función JSON_PRETTY toma un documento JSON y lo devuelve formateado con indentación y saltos de línea, haciéndolo fácil de leer para los humanos. MySQL almacena internamente los documentos JSON en un formato binario compacto y, cuando los muestra, utiliza una representación mínima sin espacios innecesarios. JSON_PRETTY añade la estructura visual que necesitas para inspeccionar y depurar datos JSON directamente desde la consola de MySQL.

Sintaxis

JSON_PRETTY(documento_json)

La función recibe una expresión JSON (columna, variable o literal) y devuelve una cadena de texto con el documento formateado. La indentación usa dos espacios por nivel de anidamiento. Los elementos de arrays y los pares clave-valor de objetos aparecen en líneas separadas. El orden de las claves en los objetos se mantiene según el orden interno de MySQL (que ordena las claves por longitud y luego alfabéticamente).

Comportamiento básico

Empecemos con un objeto JSON simple para ver la diferencia entre la representación compacta y la formateada:

SELECT JSON_PRETTY('{"nombre":"iPhone 15 Pro","precio":1299.99,"disponible":true}') AS resultado;
{
  "nombre": "iPhone 15 Pro",
  "precio": 1299.99,
  "disponible": true
}

Sin JSON_PRETTY, el mismo documento se muestra en una sola línea. Con la función aplicada, cada par clave-valor aparece en su propia línea con dos espacios de indentación.

Con estructuras anidadas, la indentación refleja la profundidad:

SELECT JSON_PRETTY('{
    "producto": "MacBook Air M3",
    "especificaciones": {
        "procesador": "Apple M3",
        "ram": "16GB",
        "almacenamiento": "512GB SSD"
    },
    "colores": ["Medianoche", "Luz estelar", "Gris espacial", "Plata"]
}') AS resultado;
{
  "colores": [
    "Medianoche",
    "Luz estelar",
    "Gris espacial",
    "Plata"
  ],
  "producto": "MacBook Air M3",
  "especificaciones": {
    "ram": "16GB",
    "procesador": "Apple M3",
    "almacenamiento": "512GB SSD"
  }
}

Observa que MySQL reordena las claves (las ordena por longitud y luego alfabéticamente en su representación interna). El contenido es idéntico, solo cambia el orden de presentación de las claves.

Caso práctico: inspeccionar datos almacenados

Cuando almacenas JSON en columnas de tu base de datos, JSON_PRETTY es la herramienta ideal para examinar el contenido de forma legible:

CREATE TABLE productos (
    id INT AUTO_INCREMENT PRIMARY KEY,
    nombre VARCHAR(200),
    atributos JSON
);
 
INSERT INTO productos (nombre, atributos) VALUES
('iPhone 15 Pro', '{
    "color": "Titanio Natural",
    "almacenamiento": "256GB",
    "chip": "A17 Pro",
    "pantalla": {"tamanio": 6.1, "tipo": "Super Retina XDR", "tasa_refresco": 120},
    "camaras": [
        {"tipo": "principal", "megapixeles": 48},
        {"tipo": "ultra_angular", "megapixeles": 12},
        {"tipo": "teleobjetivo", "megapixeles": 12}
    ]
}');
SELECT JSON_PRETTY(atributos) AS especificaciones
FROM productos
WHERE nombre = 'iPhone 15 Pro';
{
  "chip": "A17 Pro",
  "color": "Titanio Natural",
  "camaras": [
    {
      "tipo": "principal",
      "megapixeles": 48
    },
    {
      "tipo": "ultra_angular",
      "megapixeles": 12
    },
    {
      "tipo": "teleobjetivo",
      "megapixeles": 12
    }
  ],
  "pantalla": {
    "tipo": "Super Retina XDR",
    "tamanio": 6.1,
    "tasa_refresco": 120
  },
  "almacenamiento": "256GB"
}

Sin JSON_PRETTY, todo este contenido aparecería en una sola línea extremadamente larga, difícil de analizar visualmente. Con la función, cada nivel de anidamiento queda claramente diferenciado.

Caso práctico: depurar configuraciones

Cuando las aplicaciones almacenan configuraciones en formato JSON, JSON_PRETTY facilita la revisión rápida:

CREATE TABLE configuraciones_app (
    id INT AUTO_INCREMENT PRIMARY KEY,
    entorno VARCHAR(20),
    config JSON
);
 
INSERT INTO configuraciones_app (entorno, config) VALUES
('produccion', '{
    "base_datos": {"host": "db.empresa.com", "puerto": 3306, "pool_size": 20, "ssl": true},
    "cache": {"driver": "redis", "host": "cache.empresa.com", "ttl": 3600},
    "correo": {"smtp_host": "smtp.empresa.com", "smtp_puerto": 587, "seguridad": "TLS"},
    "logs": {"nivel": "warning", "rotacion": "diaria", "max_archivos": 30}
}');
SELECT
    entorno,
    JSON_PRETTY(config) AS configuracion
FROM configuraciones_app
WHERE entorno = 'produccion';

El resultado formateado permite inspeccionar cada sección de la configuración de un vistazo, identificar valores incorrectos y comparar configuraciones entre entornos.

Caso práctico: exportar JSON legible

Si necesitas exportar datos JSON para documentación, informes o comunicación con otros equipos, JSON_PRETTY produce un formato que es directamente utilizable:

SELECT JSON_PRETTY(
    JSON_OBJECT(
        'fecha_reporte', CURDATE(),
        'total_productos', (SELECT COUNT(*) FROM productos),
        'productos', (
            SELECT JSON_ARRAYAGG(
                JSON_OBJECT('id', id, 'nombre', nombre)
            )
            FROM productos
        )
    )
) AS reporte;

El resultado es un documento JSON perfectamente indentado que puedes copiar y pegar directamente en un archivo, una herramienta de documentación o un mensaje.

Comparación con el almacenamiento compacto

Es importante entender que JSON_PRETTY es solo una función de presentación. No modifica los datos almacenados ni afecta al rendimiento de las consultas. MySQL siempre almacena JSON en formato binario compacto, independientemente de cómo lo insertes:

-- Ambas inserciones almacenan exactamente los mismos bytes:
INSERT INTO productos (nombre, atributos) VALUES
('Producto A', '{"clave": "valor"}');
 
INSERT INTO productos (nombre, atributos) VALUES
('Producto B', '{
    "clave": "valor"
}');

Los espacios y saltos de línea del JSON de entrada se descartan durante el almacenamiento. Cuando consultas los datos sin JSON_PRETTY, obtienes la representación compacta. JSON_PRETTY solo formatea la salida en el momento de la consulta.

Manejo de NULL

Si el argumento es NULL, JSON_PRETTY devuelve NULL:

SELECT JSON_PRETTY(NULL) AS resultado;
resultado
NULL

Los valores simples (escalares) se devuelven tal cual, sin modificación:

SELECT JSON_PRETTY('"cadena simple"') AS texto,
       JSON_PRETTY('42') AS numero,
       JSON_PRETTY('true') AS booleano;
textonumerobooleano
"cadena simple"42true

Los escalares no necesitan indentación, así que la función simplemente los devuelve en su forma canónica.

Con arrays y objetos vacíos, el resultado es la representación compacta ya que no hay contenido que indentar:

SELECT JSON_PRETTY('[]') AS array_vacio,
       JSON_PRETTY('{}') AS objeto_vacio;
array_vacioobjeto_vacio
[]{}

Combinación con otras funciones

Puedes combinar JSON_PRETTY con funciones de extracción para formatear solo una parte del documento:

SELECT JSON_PRETTY(
    JSON_EXTRACT(atributos, '$.pantalla')
) AS info_pantalla
FROM productos
WHERE nombre = 'iPhone 15 Pro';
{
  "tipo": "Super Retina XDR",
  "tamanio": 6.1,
  "tasa_refresco": 120
}

También es útil combinarla con funciones de construcción para verificar visualmente el resultado de operaciones complejas:

SELECT JSON_PRETTY(
    JSON_MERGE_PATCH(
        '{"nombre": "Producto", "precio": 100, "stock": 50}',
        '{"precio": 120, "descuento": 10}'
    )
) AS resultado_merge;
{
  "stock": 50,
  "nombre": "Producto",
  "precio": 120,
  "descuento": 10
}

Este uso es particularmente valioso durante el desarrollo, cuando necesitas entender exactamente qué produce una operación JSON antes de usarla en producción.

En el siguiente artículo veremos JSON_STORAGE_SIZE para conocer el tamaño de almacenamiento.

Escrito por Eduardo Lázaro