Import ed Export JSONL da Database: PostgreSQL, MongoDB e Altri

Una guida completa all'importazione di file JSONL nei database e all'esportazione di record del database come JSONL. Copre i comandi COPY di PostgreSQL, gli strumenti CLI di MongoDB, JSON_TABLE di MySQL, script SQLite e pattern di import in blocco pronti per la produzione.

Ultimo aggiornamento: Febbraio 2026

Perché Usare JSONL per Import ed Export da Database?

JSONL (JSON Lines) è diventato un formato preferito per spostare dati tra database e sistemi esterni. Ogni riga è un oggetto JSON indipendente e autonomo, il che significa che puoi trasmettere record uno alla volta senza caricare l'intero dataset in memoria. Questo è fondamentale quando migri milioni di righe tra istanze PostgreSQL, sincronizzi collezioni MongoDB con un data warehouse o alimenti esportazioni di database in pipeline di machine learning.

Rispetto a CSV, JSONL preserva i tipi di dati, supporta oggetti e array nidificati ed elimina l'ambiguità dell'escape dei delimitatori. Un file JSONL può trasportare una colonna jsonb di PostgreSQL esattamente così com'è, mentre CSV richiederebbe di appiattire o fare l'escape della struttura nidificata. Rispetto a un array JSON completo, JSONL è in streaming: puoi elaborare, validare o trasformare ogni record nel momento in cui viene letto, piuttosto che aspettare che l'intero file venga analizzato.

Ogni sistema di database principale ora dispone di strumenti per JSONL. PostgreSQL può fare COPY delle righe tramite casting jsonb, MongoDB include mongoimport e mongoexport che usano JSONL come default, MySQL 8.0 ha aggiunto JSON_TABLE per l'estrazione strutturata, e SQLite ha un'estensione JSON1. Nelle sezioni seguenti imparerai i comandi esatti, gli script e le best practice per ogni database.

PostgreSQL: Import ed Export JSONL

PostgreSQL offre diversi approcci per lavorare con JSONL. Il comando COPY fornisce il percorso di import in blocco più veloce, mentre il tipo di dato jsonb permette di memorizzare e interrogare dati semi-strutturati nativamente. Per tabelle strutturate, puoi analizzare i campi JSONL in colonne tipizzate durante l'import.

Il modo più veloce per importare JSONL in PostgreSQL è caricare ogni riga come valore jsonb usando il comando COPY. Crea una tabella con una singola colonna jsonb, poi usa COPY FROM per trasmettere il file direttamente nel database.

Importare JSONL in una Colonna 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;

Per esportare dati come JSONL, usa row_to_json() o to_jsonb() per convertire ogni riga in un oggetto JSON, poi usa COPY per salvare il risultato in un file. Ogni riga diventa una riga nel file di output.

Esportare Righe PostgreSQL come 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",...}

Per carichi di lavoro di produzione, usa uno script Python con psycopg2 per leggere un file JSONL e inserire record in colonne tipizzate. Questo ti dà pieno controllo su validazione, gestione degli errori e dimensione dei batch.

Script Python per Import Strutturato in 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: Supporto Nativo JSONL

MongoDB ha supporto JSONL di prima classe tramite i suoi strumenti Database Tools da riga di comando. Le utility mongoimport e mongoexport usano il formato JSONL come default, rendendo MongoDB uno dei database più facili con cui lavorare per lo scambio di dati JSONL. Ogni riga in un file JSONL corrisponde direttamente a un documento MongoDB.

mongoimport legge un file JSONL e inserisce ogni riga come documento nella collezione specificata. Supporta la modalità upsert, la coercizione dei tipi di campo e l'inserimento parallelo per un throughput elevato.

Importare 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 scrive ogni documento di una collezione come una singola riga JSON. Puoi filtrare, proiettare e ordinare l'output. Il risultato è un file JSONL valido pronto per l'elaborazione da qualsiasi sistema a valle.

Esportare MongoDB in 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 e Script

MySQL non ha un comando nativo di import JSONL come MongoDB, ma MySQL 8.0 ha introdotto JSON_TABLE che permette di estrarre dati strutturati da stringhe JSON. Per l'import in blocco di JSONL, l'approccio più affidabile combina LOAD DATA INFILE per il caricamento grezzo con JSON_TABLE per l'estrazione, oppure usa un linguaggio di scripting come Python.

Carica il file JSONL come testo grezzo in una tabella di staging, poi usa JSON_TABLE per estrarre i campi in una tabella strutturata. Questo approccio in due fasi funziona interamente all'interno di MySQL.

Importare JSONL Usando una Tabella di Staging e 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;

Per maggiore flessibilità, usa uno script Python con mysql-connector-python per leggere un file JSONL e inserire record in batch. Questo approccio gestisce file di grandi dimensioni in modo efficiente e fornisce report dettagliati degli errori.

Script Python per Import JSONL in 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: Import JSONL Leggero

SQLite è un'eccellente scelta per lo sviluppo locale e dataset di dimensioni ridotte. Sebbene SQLite non abbia un comando nativo di import JSONL, la sua estensione JSON1 fornisce json_extract() per lavorare con dati JSON, e un semplice script Python può importare file JSONL in modo efficiente usando il supporto integrato alle transazioni di SQLite.

Usa il modulo sqlite3 integrato di Python per leggere un file JSONL e inserire record in un database SQLite. Racchiudere tutti gli inserimenti in una singola transazione migliora drasticamente le prestazioni per file di grandi dimensioni.

Script Python per Import JSONL in 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;

Best Practice per l'Import in Blocco

L'importazione di file JSONL di grandi dimensioni in un database richiede attenzione a transazioni, gestione degli errori e gestione delle risorse. Queste best practice si applicano a tutti i sistemi di database e ti aiuteranno a costruire pipeline di import affidabili e pronte per la produzione.

Transazioni in Batch

Prestazioni

Non inserire mai una riga per transazione. Raggruppa gli inserimenti in batch di 500-5000 righe per transazione. Questo riduce l'I/O su disco e l'overhead dei lock di 10-100x. La maggior parte dei database vede i maggiori guadagni con batch di 1000 righe. Andare oltre offre rendimenti decrescenti e aumenta il costo di un rollback in caso di errore.

Gestione Errori a Livello di Riga

Affidabilità

Analizza e valida ogni riga JSONL individualmente. Registra il numero di riga e il messaggio di errore per ogni riga che fallisce la validazione o l'inserimento. Usa ON CONFLICT / ON DUPLICATE KEY per gestire le violazioni di vincoli univoci in modo elegante anziché interrompere l'intero import. Salva le righe fallite in un file di errori separato per la revisione successiva.

Monitoraggio dell'Avanzamento

Osservabilità

Per file con milioni di righe, registra l'avanzamento ogni N record (ad esempio, ogni 10.000). Tieni traccia delle righe totali lette, degli inserimenti riusciti, dei duplicati saltati e degli errori. Calcola e mostra la velocità di import (record/secondo) per identificare i colli di bottiglia delle prestazioni. Questo feedback è essenziale per monitorare import di lunga durata.

Questo pattern generico combina batch, gestione degli errori e monitoraggio dell'avanzamento. Adattalo a qualsiasi database sostituendo la funzione di inserimento.

Pattern di Import in Batch Pronto per la Produzione
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 i Tuoi Dati con Strumenti JSONL Gratuiti

Prima di importare JSONL nel tuo database, valida il formato del file e converti tra formati. I nostri strumenti online gratuiti elaborano tutto localmente nel tuo browser, quindi i tuoi dati non lasciano mai la tua macchina.

Lavora con File JSONL Online

Visualizza, valida e converti file JSONL fino a 1GB direttamente nel tuo browser. Nessun upload richiesto, 100% privato.

Domande Frequenti

Import/Export JSONL — PostgreSQL, MongoDB, BigQuery e Alt...