Menu

SQLite-Daten exportieren: CSV, JSON & SQL-Dump per CLI

Daten aus SQLite exportieren – CSV mit Spaltenüberschriften, JSON, kompletter SQL-Dump und einzelne Tabellen sichern, alles direkt in der sqlite3-Shell.

Diese Seite enthält ausführbare Editoren — bearbeiten, ausführen und Ausgabe sofort sehen.

Exportieren ist Sache der Shell, kein SQL-Statement

SQLite kennt weder ein COPY ... TO wie Postgres noch ein SELECT INTO OUTFILE wie MySQL. Wer SQLite Daten exportieren möchte, macht das stattdessen über die sqlite3-Kommandozeile – gesteuert durch sogenannte Dot-Commands: .mode, .headers, .output und .dump. Sobald du diese vier kennst, kannst du aus jeder Datenbank CSV, JSON, einfachen Text oder einen kompletten SQL-Dump erzeugen.

Das Grundprinzip: Du sagst der Shell, wie die Ergebnisse formatiert werden sollen (.mode), ob die Spaltennamen mit dabei sein sollen (.headers) und wohin die Ausgabe geht (.output). Danach setzt du eine Abfrage ab – und deren Resultat landet direkt in der Datei.

Bauen wir uns eine kleine Beispieldatenbank zum Ausprobieren:

Drei Zeilen, vier Spalten. Diese exportieren wir gleich in mehreren Formaten.

CSV-Export: .mode csv mit Spaltenüberschriften

CSV ist das gängigste Format, um SQLite-Daten zu exportieren — Tabellenkalkulationen, Datenpipelines und so gut wie alle anderen Tools können damit umgehen. Direkt in der sqlite3-Shell sieht das so aus:

sqlite> .mode csv
sqlite> .headers on
sqlite> .output users.csv
sqlite> SELECT * FROM users;
sqlite> .output stdout

Was hier gerade passiert ist:

  • .mode csv formatiert jede Zeile als kommagetrennte Werte und setzt Felder mit Kommas, Anführungszeichen oder Zeilenumbrüchen automatisch in Anführungszeichen.
  • .headers on ergänzt eine erste Zeile mit den Spaltennamen. Ohne diese Option bekommst du eine CSV ganz ohne Kopfzeile – meistens nicht das, was du willst.
  • .output users.csv leitet die Ergebnisse in eine Datei um. Ab diesem Moment landet die Ausgabe der Abfragen dort statt im Terminal.
  • Das SELECT läuft durch und schreibt das Ergebnis still in die Datei.
  • .output stdout schaltet die Ausgabe wieder zurück aufs Terminal, damit du die Resultate der nächsten Abfrage auch sehen kannst.

Die entstandene Datei:

id,name,email,signup_date
1,"Ada Lovelace",ada@example.com,2025-01-15
2,"Boris Johnson",boris@example.com,2025-02-03
3,"Carmen Diaz",carmen@example.com,2025-03-22

Du kannst nicht nur ganze Tabellen exportieren, sondern auch das Ergebnis jeder beliebigen Abfrage – einfach filtern, joinen, aggregieren und dann umleiten:

sqlite> .output recent_users.csv
sqlite> SELECT name, email FROM users WHERE signup_date >= '2025-02-01';
sqlite> .output stdout

Einzeiler direkt aus der Shell

Du musst dafür gar nicht erst in die interaktive Shell wechseln. Leite die Dot-Commands und das SQL einfach per Pipe direkt an sqlite3 aus deiner Betriebssystem-Shell weiter:

sqlite3 mydb.sqlite <<EOF
.headers on
.mode csv
.output users.csv
SELECT * FROM users;
EOF

Das ist die Form, die du für Skripte und Cronjobs willst – wiederholbar und ohne manuelles Tippen. .output gilt nur für die aktuelle Session, der State bleibt also schön gekapselt.

JSON-Export: .mode json

Wenn der Export in eine Web-App oder ein anderes JSON-fähiges Tool wandern soll, liefert .mode json ein Array aus Objekten – ein Objekt pro Zeile:

sqlite> .mode json
sqlite> .output users.json
sqlite> SELECT * FROM users;
sqlite> .output stdout

The file:

[{"id":1,"name":"Ada Lovelace","email":"ada@example.com","signup_date":"2025-01-15"},
{"id":2,"name":"Boris Johnson","email":"boris@example.com","signup_date":"2025-02-03"},
{"id":3,"name":"Carmen Diaz","email":"carmen@example.com","signup_date":"2025-03-22"}]

Header sind in JSON ohnehin implizit (die Keys), deshalb greift .headers hier nicht. Wenn du eine eigene Struktur brauchst – verschachtelte Objekte oder umbenannte Felder – baust du sie direkt im Query mit json_object():

Damit bekommst du pro Zeile einen JSON-String mit voller Kontrolle über die Struktur. In Kombination mit json_group_array() lässt sich das komplette Ergebnis dann zu einem einzigen JSON-Dokument zusammenfassen.

Kompletter SQL-Dump mit .dump

.dump spielt in einer ganz anderen Liga als CSV oder JSON. Der Befehl erzeugt eine .sql-Datei, die sowohl das Schema als auch sämtliche Daten als CREATE TABLE- und INSERT-Anweisungen enthält — genug, um die Datenbank von Grund auf neu aufzubauen:

sqlite3 mydb.sqlite .dump > backup.sql

Ein Snippet von dem, was rauskommt:

PRAGMA foreign_keys=OFF;
BEGIN TRANSACTION;
CREATE TABLE users (
    id INTEGER PRIMARY KEY,
    name TEXT NOT NULL,
    email TEXT NOT NULL,
    signup_date TEXT NOT NULL
);
INSERT INTO users VALUES(1,'Ada Lovelace','ada@example.com','2025-01-15');
INSERT INTO users VALUES(2,'Boris Johnson','boris@example.com','2025-02-03');
INSERT INTO users VALUES(3,'Carmen Diaz','carmen@example.com','2025-03-22');
COMMIT;

Das Zurückspielen ist der umgekehrte Weg – die Datei wird einfach in eine frische Datenbank gepipet:

sqlite3 restored.sqlite < backup.sql

.dump ist das richtige Werkzeug für Backups, versionierte Snapshots von Testdaten und die Migration zwischen Rechnern. Indizes, Trigger, Views – also wirklich alles aus dem Schema – bleiben dabei erhalten.

Einzelne Tabelle als SQLite Dump exportieren

.dump akzeptiert einen Tabellennamen (oder ein Muster), um die Ausgabe einzugrenzen:

sqlite3 mydb.sqlite ".dump users" > users_only.sql

Damit werden nur das Schema und die Zeilen der Tabelle users exportiert. Praktisch, wenn du eine einzelne Tabelle in eine andere Datenbank übernehmen willst, ohne den Rest mitzuschleppen. Es funktionieren auch Muster: .dump 'log_%' exportiert alle Tabellen, deren Name mit log_ beginnt.

Schema ohne Daten exportieren

Manchmal brauchst du nur die Struktur ohne die Datensätze – für die Dokumentation, eine saubere Entwicklungsumgebung oder zum Vergleich von Schemas zwischen mehreren Datenbanken. .schema gibt ausschließlich die CREATE-Anweisungen aus:

sqlite3 mydb.sqlite .schema > schema.sql

Kombiniere ihn mit einem Tabellennamen, um nur eine bestimmte Tabelle zu erhalten:

sqlite3 mydb.sqlite ".schema users" > users_schema.sql

Die Ausgabe ist reines SQL – CREATE TABLE, CREATE INDEX, CREATE TRIGGER – und lässt sich direkt gegen eine leere Datenbank ausführen.

Weitere nützliche Ausgabemodi

.mode kann mehr als nur CSV und JSON. Diese Varianten solltest du kennen:

.mode column        -- ausgerichtete Spalten, gut zum Lesen im Terminal
.mode markdown      -- pipe-getrennt, GitHub-freundliche Tabellen
.mode html          -- HTML-<table>-Ausgabe
.mode tabs          -- tab-getrennte Werte (TSV)
.mode insert users  -- erzeugt INSERT-Anweisungen für die angegebene Tabelle
.mode quote         -- SQL-quotierte Werte, nützlich zur Inspektion

.mode markdown ist Gold wert, wenn du Abfrageergebnisse direkt in eine README oder einen Pull Request kopieren möchtest. Mit .mode insert <table> lässt sich außerdem flott Seed-Daten erzeugen — einfach ein SELECT ausführen, die generierten INSERT-Statements abgreifen und in eine Fixture-Datei einfügen.

sqlite> .mode insert users
sqlite> .output seed.sql
sqlite> SELECT * FROM users WHERE signup_date >= '2025-02-01';
sqlite> .output stdout

Ein paar praktische Hinweise

  • .output stdout (oder .output ohne Argument) leitet die Ausgabe zurück ins Terminal. Wer das vergisst, wundert sich später, warum die Ergebnisse der nächsten Abfrage einfach in der Datei verschwinden.
  • Beim CSV-Export gehen Datentypen verloren. In der Datei steht alles als Text, und beim Reimport braucht man ein passendes Zielschema, damit die Werte wieder korrekt interpretiert werden. Wenn du die Daten in eine andere SQLite-Datenbank zurückspielen willst, nimm lieber .dump.
  • Große Exporte werden gestreamt. .output schreibt die Zeilen direkt beim Erzeugen weg – du kannst also problemlos Tabellen exportieren, die größer als der verfügbare RAM sind.
  • Für ein Hot-Backup einer laufenden Datenbank funktioniert .dump zwar, aber der dedizierte Befehl .backup (kommt später im Kurs) ist schneller und sicherer, weil er die Online-Backup-API von SQLite nutzt.

Als Nächstes: Daten abfragen

Damit hast du jetzt das komplette Bild zum Schreiben von Daten – INSERT, UPDATE, DELETE, UPSERT, RETURNING, Import aus CSV und der Export zurück nach draußen. Jetzt kommt die andere Hälfte der Datenbankarbeit: Daten effizient lesen. Beim SELECT-Statement wirst du den Großteil deiner Zeit verbringen, und genau darum geht es auf der nächsten Seite.

Häufig gestellte Fragen

Wie exportiere ich eine SQLite-Tabelle als CSV?

In der sqlite3-Shell stellst du auf CSV-Modus um, schaltest die Header an und leitest die Ausgabe in eine Datei: .mode csv, .headers on, .output users.csv, anschließend SELECT * FROM users;. Danach mit .output stdout die Ausgabe wieder ins Terminal zurückholen, sonst landet alles Weitere weiter in der Datei.

Was ist der Unterschied zwischen .dump und einem CSV-Export?

.dump erzeugt eine .sql-Datei mit allen CREATE TABLE- und INSERT-Statements – also alles, was du brauchst, um die Datenbank von Grund auf wieder aufzubauen. CSV enthält dagegen nur die Zeilen einer einzelnen Abfrage oder Tabelle, ohne Schema. Kurz gesagt: .dump für Backups und Migrationen, CSV, wenn die Daten in Excel oder ein anderes Tool sollen.

Kann ich SQLite-Abfrageergebnisse als JSON exportieren?

Ja. Entweder du setzt in der Shell .mode json und führst ein beliebiges SELECT aus, oder du baust das JSON direkt in der Query mit den eingebauten Funktionen json_object() und json_group_array() zusammen. .mode json ist am schnellsten für Ad-hoc-Exporte; mit den JSON-Funktionen hast du dafür volle Kontrolle über die Struktur des Outputs.

Coddy programming languages illustration

Lerne mit Coddy zu programmieren

LOS GEHT'S