Import i eksport JSONL do baz danych: PostgreSQL, MongoDB i inne

Kompleksowy przewodnik po importowaniu plików JSONL do baz danych i eksportowaniu rekordów baz danych jako JSONL. Obejmuje polecenia PostgreSQL COPY, narzędzia CLI MongoDB, MySQL JSON_TABLE, skrypty SQLite i gotowe do produkcji wzorce importu masowego.

Ostatnia aktualizacja: luty 2026

Dlaczego warto używać JSONL do importu i eksportu baz danych?

JSONL (JSON Lines) stał się preferowanym formatem do przenoszenia danych między bazami danych a systemami zewnętrznymi. Każda linia jest niezależnym, samodzielnym obiektem JSON, co oznacza, że możesz strumieniować rekordy jeden po drugim bez ładowania całego zbioru danych do pamięci. Jest to kluczowe przy migracji milionów wierszy między instancjami PostgreSQL, synchronizacji kolekcji MongoDB z hurtownią danych lub przekazywaniu eksportów baz danych do potoków uczenia maszynowego.

W porównaniu z CSV, JSONL zachowuje typy danych, obsługuje zagnieżdżone obiekty i tablice oraz eliminuje niejednoznaczność unikania delimitrów. Plik JSONL może przenosić kolumnę PostgreSQL jsonb dokładnie w takiej postaci, w jakiej jest, podczas gdy CSV wymagałoby spłaszczenia lub unikania zagnieżdżonej struktury. W porównaniu z pełną tablicą JSON, JSONL jest strumieniowalne: możesz przetwarzać, walidować lub przekształcać każdy rekord w momencie jego odczytania, zamiast czekać na sparsowanie całego pliku.

Każdy główny system baz danych ma teraz narzędzia do JSONL. PostgreSQL może COPY wiersze przez rzutowanie jsonb, MongoDB jest dostarczany z mongoimport i mongoexport, które domyślnie używają JSONL, MySQL 8.0 dodał JSON_TABLE do ustrukturyzowanej ekstrakcji, a SQLite ma rozszerzenie JSON1. W poniższych sekcjach poznasz dokładne polecenia, skrypty i najlepsze praktyki dla każdej bazy danych.

PostgreSQL: Import i eksport JSONL

PostgreSQL oferuje kilka podejść do pracy z JSONL. Polecenie COPY zapewnia najszybszą ścieżkę importu masowego, podczas gdy typ danych jsonb pozwala przechowywać i odpytywać dane semi-ustrukturyzowane natywnie. Dla tabel ustrukturyzowanych możesz parsować pola JSONL do typowanych kolumn podczas importu.

Najszybszym sposobem importu JSONL do PostgreSQL jest załadowanie każdej linii jako wartości jsonb za pomocą polecenia COPY. Utwórz tabelę z pojedynczą kolumną jsonb, a następnie użyj COPY FROM, aby strumieniować plik bezpośrednio do bazy danych.

Import JSONL do kolumny 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;

Aby wyeksportować dane jako JSONL, użyj row_to_json() lub to_jsonb() do konwersji każdego wiersza na obiekt JSON, a następnie COPY wynik do pliku. Każdy wiersz staje się jedną linią w pliku wyjściowym.

Eksport wierszy PostgreSQL jako 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",...}

Do obciążeń produkcyjnych użyj skryptu Python z psycopg2, aby odczytać plik JSONL i wstawić rekordy do typowanych kolumn. Daje to pełną kontrolę nad walidacją, obsługą błędów i rozmiarem partii.

Skrypt Python do ustrukturyzowanego importu 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: Natywna obsługa JSONL

MongoDB ma pierwszorzędną obsługę JSONL dzięki narzędziom wiersza poleceń Database Tools. Narzędzia mongoimport i mongoexport domyślnie używają formatu JSONL, co czyni MongoDB jedną z najłatwiejszych baz danych do pracy z wymianą danych JSONL. Każda linia w pliku JSONL mapuje się bezpośrednio na dokument MongoDB.

mongoimport odczytuje plik JSONL i wstawia każdą linię jako dokument do określonej kolekcji. Obsługuje tryb upsert, wymuszanie typów pól i równoległe wstawianie dla wysokiej przepustowości.

Import JSONL za pomocą 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 zapisuje każdy dokument w kolekcji jako pojedynczą linię JSON. Możesz filtrować, projektować i sortować wyjście. Wynik jest prawidłowym plikiem JSONL gotowym do przetworzenia przez dowolny system docelowy.

Eksport MongoDB do JSONL za pomocą 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 z JSON_TABLE i skryptami

MySQL nie ma wbudowanego polecenia importu JSONL jak MongoDB, ale MySQL 8.0 wprowadził JSON_TABLE, który pozwala ekstraować ustrukturyzowane dane z ciągów JSON. Do masowego importu JSONL najbardziej niezawodne podejście łączy LOAD DATA INFILE do surowego ładowania z JSON_TABLE do ekstrakcji lub używa języka skryptowego, takiego jak Python.

Załaduj plik JSONL jako surowy tekst do tabeli tymczasowej, a następnie użyj JSON_TABLE do ekstrakcji pól do tabeli ustrukturyzowanej. To dwuetapowe podejście działa w całości w MySQL.

Import JSONL za pomocą tabeli tymczasowej i 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;

Dla większej elastyczności użyj skryptu Python z mysql-connector-python, aby odczytać plik JSONL i wsadowo wstawić rekordy. To podejście efektywnie obsługuje duże pliki i zapewnia szczegółowe raportowanie błędów.

Skrypt Python do importu JSONL do 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: Lekki import JSONL

SQLite jest doskonałym wyborem do lokalnego rozwoju i mniejszych zbiorów danych. Chociaż SQLite nie ma natywnego polecenia importu JSONL, jego rozszerzenie JSON1 udostępnia json_extract() do pracy z danymi JSON, a prosty skrypt Python może importować pliki JSONL efektywnie, korzystając z wbudowanej obsługi transakcji SQLite.

Użyj wbudowanego modułu sqlite3 Python, aby odczytać plik JSONL i wstawić rekordy do bazy danych SQLite. Zawinięcie wszystkich wstawek w jedną transakcję dramatycznie poprawia wydajność dla dużych plików.

Skrypt Python do importu JSONL do 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;

Najlepsze praktyki importu masowego

Import dużych plików JSONL do bazy danych wymaga starannej uwagi na transakcje, obsługę błędów i zarządzanie zasobami. Te najlepsze praktyki mają zastosowanie we wszystkich systemach baz danych i pomogą Ci budować niezawodne, gotowe do produkcji potoki importu.

Transakcje wsadowe

Wydajność

Nigdy nie wstawiaj jednego wiersza na transakcję. Grupuj wstawki w partie 500-5000 wierszy na transakcję. Zmniejsza to obciążenie dyskowe I/O i blokad o 10-100x. Większość baz danych osiąga największe korzyści przy partiach o rozmiarze 1000. Większe partie oferują malejące korzyści i zwiększają koszt wycofania, jeśli coś się nie powiedzie.

Obsługa błędów na poziomie linii

Niezawodność

Parsuj i waliduj każdą linię JSONL indywidualnie. Loguj numer linii i komunikat błędu dla każdej linii, która nie przejdzie walidacji lub wstawiania. Użyj ON CONFLICT / ON DUPLICATE KEY do łagodnej obsługi naruszeń ograniczeń unikalności zamiast przerywania całego importu. Zapisuj nieudane linie do osobnego pliku błędów do późniejszego przeglądu.

Śledzenie postępu

Obserwowalność

Dla plików z milionami linii loguj postęp co N rekordów (na przykład co 10 000). Śledź łączną liczbę odczytanych linii, udane wstawienia, pominięte duplikaty i błędy. Obliczaj i wyświetlaj szybkość importu (rekordy/sekundę), aby identyfikować wąskie gardła wydajności. Ta informacja zwrotna jest niezbędna do monitorowania długotrwałych importów.

Ten generyczny wzorzec łączy wsadowość, obsługę błędów i śledzenie postępu. Dostosuj go do dowolnej bazy danych, wymieniając funkcję wstawiania.

Gotowy do produkcji wzorzec importu wsadowego
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

Przygotuj swoje dane za pomocą bezpłatnych narzędzi JSONL

Przed importem JSONL do bazy danych zwaliduj format pliku i konwertuj między formatami. Nasze bezpłatne narzędzia online przetwarzają wszystko lokalnie w Twojej przeglądarce, więc dane nigdy nie opuszczają Twojego komputera.

Pracuj z plikami JSONL online

Przeglądaj, waliduj i konwertuj pliki JSONL do 1GB bezpośrednio w przeglądarce. Bez przesyłania, 100% prywatności.

Najczęściej zadawane pytania

Import/eksport JSONL — PostgreSQL, MongoDB, BigQuery i wi...