Importacion y Exportacion de JSONL en Bases de Datos: PostgreSQL, MongoDB y Mas

Una guia completa para importar archivos JSONL a bases de datos y exportar registros de bases de datos como JSONL. Cubre comandos COPY de PostgreSQL, herramientas CLI de MongoDB, JSON_TABLE de MySQL, scripts de SQLite y patrones de importacion masiva listos para produccion.

Ultima actualizacion: febrero 2026

Por que Usar JSONL para Importacion y Exportacion de Bases de Datos?

JSONL (JSON Lines) se ha convertido en un formato preferido para mover datos entre bases de datos y sistemas externos. Cada linea es un objeto JSON independiente y autocontenido, lo que significa que puedes transmitir registros uno a la vez sin cargar todo el dataset en memoria. Esto es critico cuando estas migrando millones de filas entre instancias de PostgreSQL, sincronizando colecciones de MongoDB con un data warehouse o alimentando exportaciones de bases de datos a pipelines de aprendizaje automatico.

Comparado con CSV, JSONL preserva los tipos de datos, soporta objetos y arrays anidados y elimina la ambiguedad del escape de delimitadores. Un archivo JSONL puede transportar una columna jsonb de PostgreSQL exactamente tal cual, mientras que CSV requeriria que aplanes o escapes la estructura anidada. Comparado con un array JSON completo, JSONL es transmisible: puedes procesar, validar o transformar cada registro en el momento en que se lee, en lugar de esperar a que se parsee el archivo completo.

Todos los principales sistemas de bases de datos ahora tienen herramientas para JSONL. PostgreSQL puede hacer COPY de filas mediante conversion a jsonb, MongoDB viene con mongoimport y mongoexport que usan JSONL por defecto, MySQL 8.0 agrego JSON_TABLE para extraccion estructurada y SQLite tiene una extension JSON1. En las siguientes secciones, aprenderas los comandos exactos, scripts y mejores practicas para cada base de datos.

PostgreSQL: Importar y Exportar JSONL

PostgreSQL ofrece varios enfoques para trabajar con JSONL. El comando COPY proporciona la ruta de importacion masiva mas rapida, mientras que el tipo de datos jsonb te permite almacenar y consultar datos semi-estructurados de forma nativa. Para tablas estructuradas, puedes parsear campos JSONL en columnas tipadas durante la importacion.

La forma mas rapida de importar JSONL a PostgreSQL es cargar cada linea como un valor jsonb usando el comando COPY. Crea una tabla con una unica columna jsonb, luego usa COPY FROM para transmitir el archivo directamente a la base de datos.

Importar JSONL a una Columna jsonb
-- Create a staging table with a single jsonb column
CREATE TABLE staging_import (data jsonb);
-- Import the JSONL file (each line becomes one row)
\COPY staging_import (data) FROM 'users.jsonl';
-- Verify the import
SELECT count(*) FROM staging_import;
SELECT data->>'name' AS name, data->>'email' AS email
FROM staging_import
LIMIT 5;
-- Move data into a structured table
INSERT INTO users (name, email, age)
SELECT
data->>'name',
data->>'email',
(data->>'age')::int
FROM staging_import;

Para exportar datos como JSONL, usa row_to_json() o to_jsonb() para convertir cada fila en un objeto JSON, luego haz COPY del resultado a un archivo. Cada fila se convierte en una linea en el archivo de salida.

Exportar Filas de PostgreSQL como JSONL
-- Export entire table as JSONL
\COPY (
SELECT row_to_json(t)
FROM (SELECT id, name, email, created_at FROM users) t
) TO 'users_export.jsonl';
-- Export with filtering and transformation
\COPY (
SELECT row_to_json(t)
FROM (
SELECT id, name, email,
created_at::text AS created_at
FROM users
WHERE active = true
ORDER BY id
) t
) TO 'active_users.jsonl';
-- Verify: each line is valid JSON
-- {"id":1,"name":"Alice","email":"alice@example.com",...}

Para cargas de trabajo de produccion, usa un script Python con psycopg2 para leer un archivo JSONL e insertar registros en columnas tipadas. Esto te da control total sobre la validacion, manejo de errores y tamano de lotes.

Script Python para Importacion Estructurada en PostgreSQL
import json
import psycopg2
from psycopg2.extras import execute_values
def import_jsonl_to_postgres(file_path, conn_string):
conn = psycopg2.connect(conn_string)
cur = conn.cursor()
batch = []
batch_size = 1000
total = 0
with open(file_path, 'r') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line:
continue
try:
record = json.loads(line)
batch.append((
record['name'],
record['email'],
record.get('age'),
))
except (json.JSONDecodeError, KeyError) as e:
print(f"Skipping line {line_num}: {e}")
continue
if len(batch) >= batch_size:
execute_values(
cur,
"INSERT INTO users (name, email, age) "
"VALUES %s ON CONFLICT (email) DO NOTHING",
batch
)
total += len(batch)
batch = []
print(f"Imported {total} records...")
if batch:
execute_values(
cur,
"INSERT INTO users (name, email, age) "
"VALUES %s ON CONFLICT (email) DO NOTHING",
batch
)
total += len(batch)
conn.commit()
cur.close()
conn.close()
print(f"Done. Imported {total} records.")
# Usage
import_jsonl_to_postgres('users.jsonl', 'postgresql://localhost/mydb')

MongoDB: Soporte Nativo para JSONL

MongoDB tiene soporte de primera clase para JSONL a traves de sus herramientas de linea de comandos Database Tools. Las utilidades mongoimport y mongoexport usan el formato JSONL por defecto, lo que hace de MongoDB una de las bases de datos mas faciles para trabajar con intercambio de datos JSONL. Cada linea en un archivo JSONL se mapea directamente a un documento MongoDB.

mongoimport lee un archivo JSONL e inserta cada linea como un documento en la coleccion especificada. Soporta modo upsert, coercion de tipos de campos e insercion paralela para alto rendimiento.

Importar JSONL con mongoimport
# Basic import: each line becomes a document
mongoimport \
--uri="mongodb://localhost:27017/mydb" \
--collection=users \
--file=users.jsonl
# Upsert mode: update existing documents by _id
mongoimport \
--uri="mongodb://localhost:27017/mydb" \
--collection=users \
--file=users.jsonl \
--mode=upsert \
--upsertFields=email
# Drop collection before import (clean slate)
mongoimport \
--uri="mongodb://localhost:27017/mydb" \
--collection=users \
--file=users.jsonl \
--drop
# Import with parallel workers for large files
mongoimport \
--uri="mongodb://localhost:27017/mydb" \
--collection=users \
--file=large_users.jsonl \
--numInsertionWorkers=4

mongoexport escribe cada documento de una coleccion como una unica linea JSON. Puedes filtrar, proyectar y ordenar la salida. El resultado es un archivo JSONL valido listo para ser procesado por cualquier sistema posterior.

Exportar MongoDB a JSONL con mongoexport
# Export entire collection as JSONL (default format)
mongoexport \
--uri="mongodb://localhost:27017/mydb" \
--collection=users \
--out=users_export.jsonl
# Export with query filter
mongoexport \
--uri="mongodb://localhost:27017/mydb" \
--collection=users \
--query={"active": true} \
--out=active_users.jsonl
# Export specific fields only
mongoexport \
--uri="mongodb://localhost:27017/mydb" \
--collection=users \
--fields=name,email,created_at \
--out=users_partial.jsonl
# Export with sorting
mongoexport \
--uri="mongodb://localhost:27017/mydb" \
--collection=users \
--sort={"created_at": -1} \
--out=users_sorted.jsonl

MySQL: JSONL con JSON_TABLE y Scripts

MySQL no tiene un comando de importacion JSONL integrado como MongoDB, pero MySQL 8.0 introdujo JSON_TABLE que te permite extraer datos estructurados de cadenas JSON. Para importacion masiva de JSONL, el enfoque mas confiable combina LOAD DATA INFILE para carga bruta con JSON_TABLE para extraccion, o usa un lenguaje de scripting como Python.

Carga el archivo JSONL como texto crudo en una tabla de staging, luego usa JSON_TABLE para extraer campos en una tabla estructurada. Este enfoque de dos pasos funciona completamente dentro de MySQL.

Importar JSONL Usando una Tabla de Staging y JSON_TABLE
-- Step 1: Create a staging table for raw lines
CREATE TABLE jsonl_staging (
id INT AUTO_INCREMENT PRIMARY KEY,
raw_line TEXT NOT NULL
);
-- Step 2: Load the JSONL file as raw text
LOAD DATA INFILE '/var/lib/mysql-files/users.jsonl'
INTO TABLE jsonl_staging
LINES TERMINATED BY '\n'
(raw_line);
-- Step 3: Extract structured data with JSON_TABLE
INSERT INTO users (name, email, age)
SELECT jt.name, jt.email, jt.age
FROM jsonl_staging,
JSON_TABLE(
raw_line, '$'
COLUMNS (
name VARCHAR(255) PATH '$.name',
email VARCHAR(255) PATH '$.email',
age INT PATH '$.age'
)
) AS jt;
-- Step 4: Clean up staging table
DROP TABLE jsonl_staging;
-- Verify the import
SELECT * FROM users LIMIT 5;

Para mas flexibilidad, usa un script Python con mysql-connector-python para leer un archivo JSONL e insertar registros por lotes. Este enfoque maneja archivos grandes de forma eficiente y proporciona informes de errores detallados.

Script Python para Importacion JSONL en MySQL
import json
import mysql.connector
def import_jsonl_to_mysql(file_path, config):
conn = mysql.connector.connect(**config)
cursor = conn.cursor()
batch = []
batch_size = 1000
total = 0
insert_sql = (
"INSERT INTO users (name, email, age) "
"VALUES (%s, %s, %s) "
"ON DUPLICATE KEY UPDATE name=VALUES(name)"
)
with open(file_path, 'r') as f:
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line:
continue
try:
record = json.loads(line)
batch.append((
record['name'],
record['email'],
record.get('age'),
))
except (json.JSONDecodeError, KeyError) as e:
print(f"Skipping line {line_num}: {e}")
continue
if len(batch) >= batch_size:
cursor.executemany(insert_sql, batch)
conn.commit()
total += len(batch)
batch = []
print(f"Imported {total} records...")
if batch:
cursor.executemany(insert_sql, batch)
conn.commit()
total += len(batch)
cursor.close()
conn.close()
print(f"Done. Imported {total} records.")
# Usage
import_jsonl_to_mysql('users.jsonl', {
'host': 'localhost',
'user': 'root',
'password': 'secret',
'database': 'mydb'
})

SQLite: Importacion Ligera de JSONL

SQLite es una excelente opcion para desarrollo local y datasets mas pequenos. Aunque SQLite no tiene un comando de importacion JSONL nativo, su extension JSON1 proporciona json_extract() para trabajar con datos JSON, y un simple script Python puede importar archivos JSONL de manera eficiente usando el soporte integrado de transacciones de SQLite.

Usa el modulo sqlite3 integrado de Python para leer un archivo JSONL e insertar registros en una base de datos SQLite. Envolver todas las inserciones en una unica transaccion mejora dramaticamente el rendimiento para archivos grandes.

Script Python para Importacion JSONL en SQLite
import json
import sqlite3
def import_jsonl_to_sqlite(jsonl_path, db_path):
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
# Create table if it doesn't exist
cursor.execute("""
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
email TEXT UNIQUE,
age INTEGER,
raw_json TEXT
)
""")
total = 0
errors = 0
with open(jsonl_path, 'r') as f:
# Use a transaction for bulk insert performance
conn.execute('BEGIN TRANSACTION')
for line_num, line in enumerate(f, 1):
line = line.strip()
if not line:
continue
try:
record = json.loads(line)
cursor.execute(
"INSERT OR IGNORE INTO users "
"(name, email, age, raw_json) "
"VALUES (?, ?, ?, ?)",
(
record['name'],
record.get('email'),
record.get('age'),
line, # Store original JSON
)
)
total += 1
except (json.JSONDecodeError, KeyError) as e:
errors += 1
print(f"Line {line_num}: {e}")
conn.commit()
conn.close()
print(f"Imported {total} records, {errors} errors")
# Usage
import_jsonl_to_sqlite('users.jsonl', 'app.db')
# Query with json_extract (SQLite JSON1 extension)
# SELECT json_extract(raw_json, '$.name') FROM users;

Mejores Practicas de Importacion Masiva

Importar archivos JSONL grandes a una base de datos requiere atencion cuidadosa a las transacciones, manejo de errores y gestion de recursos. Estas mejores practicas se aplican a todos los sistemas de bases de datos y te ayudaran a construir pipelines de importacion confiables y listos para produccion.

Transacciones por Lotes

Rendimiento

Nunca insertes una fila por transaccion. Agrupa las inserciones en lotes de 500-5000 filas por transaccion. Esto reduce el I/O de disco y la sobrecarga de bloqueos entre 10 y 100 veces. La mayoria de las bases de datos ven las mayores ganancias con tamanos de lote de 1000. Ir mas grande ofrece retornos decrecientes y aumenta el costo de un rollback si algo falla.

Manejo de Errores por Linea

Confiabilidad

Parsea y valida cada linea JSONL individualmente. Registra el numero de linea y el mensaje de error para cualquier linea que falle la validacion o insercion. Usa ON CONFLICT / ON DUPLICATE KEY para manejar violaciones de restricciones unicas de forma elegante en lugar de abortar toda la importacion. Guarda las lineas fallidas en un archivo de errores separado para revision posterior.

Seguimiento de Progreso

Observabilidad

Para archivos con millones de lineas, registra el progreso cada N registros (por ejemplo, cada 10,000). Rastrea el total de lineas leidas, inserciones exitosas, duplicados omitidos y errores. Calcula y muestra la tasa de importacion (registros/segundo) para identificar cuellos de botella de rendimiento. Esta retroalimentacion es esencial para monitorear importaciones de larga duracion.

Este patron generico combina agrupacion por lotes, manejo de errores y seguimiento de progreso. Adaptalo a cualquier base de datos intercambiando la funcion de insercion.

Patron de Importacion por Lotes Listo para Produccion
import json
import time
def batch_import_jsonl(file_path, insert_fn, batch_size=1000):
"""Generic JSONL batch importer with error handling."""
batch = []
stats = {
'total_lines': 0,
'imported': 0,
'skipped': 0,
'errors': 0
}
start_time = time.time()
error_file = open(file_path + '.errors', 'w')
with open(file_path, 'r') as f:
for line_num, line in enumerate(f, 1):
stats['total_lines'] = line_num
line = line.strip()
if not line:
stats['skipped'] += 1
continue
try:
record = json.loads(line)
batch.append(record)
except json.JSONDecodeError as e:
stats['errors'] += 1
error_file.write(f"{line_num}\t{e}\t{line}\n")
continue
if len(batch) >= batch_size:
inserted = insert_fn(batch)
stats['imported'] += inserted
batch = []
if line_num % 10000 == 0:
elapsed = time.time() - start_time
rate = stats['imported'] / elapsed
print(
f"Progress: {line_num:,} lines | "
f"{stats['imported']:,} imported | "
f"{rate:,.0f} records/sec"
)
# Flush remaining batch
if batch:
inserted = insert_fn(batch)
stats['imported'] += inserted
error_file.close()
elapsed = time.time() - start_time
print(f"\nComplete in {elapsed:.1f}s")
print(f" Lines: {stats['total_lines']:,}")
print(f" Imported: {stats['imported']:,}")
print(f" Errors: {stats['errors']:,}")
return stats

Prepara tus Datos con Herramientas JSONL Gratuitas

Antes de importar JSONL a tu base de datos, valida el formato del archivo y convierte entre formatos. Nuestras herramientas online gratuitas procesan todo localmente en tu navegador, asi que tus datos nunca salen de tu maquina.

Trabaja con Archivos JSONL Online

Visualiza, valida y convierte archivos JSONL de hasta 1GB directamente en tu navegador. Sin subidas necesarias, 100% privado.

Preguntas Frecuentes

Importar/Exportar JSONL — PostgreSQL, MongoDB, BigQuery y...