Exportar datos en SQLite es tarea de la shell, no de SQL
SQLite no tiene un COPY ... TO ni un SELECT INTO OUTFILE como Postgres o MySQL. Aquí, exportar datos se hace desde la shell de sqlite3 mediante los llamados dot-commands: .mode, .headers, .output y .dump. Con esos cuatro en el bolsillo ya puedes generar CSV, JSON, texto plano o un volcado SQL completo de cualquier base de datos.
La idea es sencilla: le indicas a la shell cómo formatear los resultados (.mode), si quieres incluir las cabeceras de columna (.headers) y adónde mandar la salida (.output). Después lanzas la consulta y sus resultados aterrizan en el archivo.
Vamos a montar una pequeña base de datos para ir practicando:
Tres filas y cuatro columnas. Vamos a exportar esto en varios formatos.
Exportar SQLite a CSV: .mode csv con cabeceras
CSV es el formato de exportación más habitual: hojas de cálculo, pipelines de datos y la mayoría de herramientas lo entienden sin problema. Dentro del shell de sqlite3:
sqlite> .mode csv
sqlite> .headers on
sqlite> .output users.csv
sqlite> SELECT * FROM users;
sqlite> .output stdout
Qué acaba de pasar:
.mode csvda formato a cada fila como valores separados por comas, entrecomillando los campos que contengan comas, comillas o saltos de línea..headers onañade una primera fila con los nombres de las columnas. Sin esto, tu CSV se queda sin cabecera, y normalmente no es lo que quieres..output users.csvredirige los resultados a un archivo. A partir de ese momento, la salida de las consultas va al archivo en lugar de a la pantalla.- El
SELECTse ejecuta y escribe en el archivo sin mostrar nada. .output stdoutdevuelve la salida al terminal, para que puedas ver los resultados de la siguiente consulta.
El archivo resultante:
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
Puedes exportar el resultado de cualquier consulta, no solo tablas completas: filtra, haz JOINs, agrega y luego redirige la salida:
sqlite> .output recent_users.csv
sqlite> SELECT name, email FROM users WHERE signup_date >= '2025-02-01';
sqlite> .output stdout
Una sola línea desde la terminal
No hace falta entrar al shell interactivo. Puedes pasarle los dot-commands y el SQL directamente a sqlite3 desde la terminal de tu sistema operativo:
sqlite3 mydb.sqlite <<EOF
.headers on
.mode csv
.output users.csv
SELECT * FROM users;
EOF
Esta es la forma que querrás usar en scripts y trabajos cron: repetible y sin teclear nada a mano. El .output es local a la sesión, así que no deja estado regado por ahí.
JSON: .mode json
Cuando la exportación va a parar a una app web o a una herramienta que consume JSON, .mode json genera un array de objetos, uno por fila:
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"}]
En JSON las cabeceras van implícitas (son las propias claves), así que .headers no pinta nada aquí. Si quieres darle otra forma —objetos anidados, campos renombrados— móntalo desde la propia consulta con json_object():
Así obtienes cadenas JSON por fila con control total sobre la estructura. Si lo combinas con json_group_array(), puedes empaquetar todo el resultado en un único documento JSON.
Volcar la base de datos completa: .dump
.dump juega en otra liga, distinta de CSV o JSON. Genera un archivo .sql que incluye el esquema y todos los datos en forma de sentencias CREATE TABLE e INSERT — todo lo necesario para reconstruir la base de datos desde cero:
sqlite3 mydb.sqlite .dump > backup.sql
Un fragmento de lo que aparece:
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;
Restaurar es la operación inversa: basta con redirigir el archivo a una base de datos nueva:
sqlite3 restored.sqlite < backup.sql
.dump es la herramienta ideal para hacer copias de seguridad, guardar snapshots de datos de prueba en el control de versiones y migrar entre máquinas. Conserva índices, triggers, vistas... todo lo que haya en el esquema.
Volcar una sola tabla
.dump admite un nombre de tabla (o un patrón) para acotar la salida:
sqlite3 mydb.sqlite ".dump users" > users_only.sql
Eso vuelca únicamente el esquema y las filas de la tabla users. Va de perlas cuando quieres copiar una sola tabla a otra base de datos sin arrastrar lo demás. También admite patrones: .dump 'log_%' vuelca todas las tablas cuyo nombre empiece por log_.
Esquema sin datos
A veces te interesa la estructura sin las filas, ya sea para documentar, montar un entorno de desarrollo limpio o comparar esquemas entre bases de datos. El comando .schema imprime solo las sentencias CREATE:
sqlite3 mydb.sqlite .schema > schema.sql
Y si le pasas el nombre de una tabla, te exporta solo esa:
sqlite3 mydb.sqlite ".schema users" > users_schema.sql
La salida es SQL puro — CREATE TABLE, CREATE INDEX, CREATE TRIGGER — listo para ejecutar contra una base de datos vacía.
Otros modos útiles
.mode ofrece muchas más opciones además de CSV y JSON. Estos son algunos que vale la pena conocer:
.mode column -- columnas alineadas, útil para leer en la terminal
.mode markdown -- separado por pipes, tablas compatibles con GitHub
.mode html -- salida en <table> HTML
.mode tabs -- valores separados por tabulaciones (TSV)
.mode insert users -- genera sentencias INSERT para la tabla indicada
.mode quote -- valores entrecomillados al estilo SQL, útil para inspección
.mode markdown te viene de maravilla cuando quieres pegar el resultado de una consulta en un README o en un pull request. .mode insert <tabla> es un truco rápido para generar datos de prueba: lanzas un SELECT, copias las sentencias INSERT que se generan y las pegas en tu archivo de fixtures.
sqlite> .mode insert users
sqlite> .output seed.sql
sqlite> SELECT * FROM users WHERE signup_date >= '2025-02-01';
sqlite> .output stdout
Algunas notas prácticas
.output stdout(o.outputsin argumentos) devuelve la salida a la terminal. Si lo olvidas, los resultados de la siguiente consulta se irán al archivo en silencio y no verás nada.- Al exportar a CSV se pierden los tipos. En el archivo todo queda como texto, y al reimportarlo necesitas un esquema de destino que sepa cómo interpretarlo. Si lo que te importa es ir y volver entre bases SQLite, usa
.dump. - Las exportaciones grandes se hacen en streaming.
.outputva escribiendo las filas a medida que se generan, así que puedes volcar tablas más grandes que la RAM sin problema. - Para una copia de seguridad en caliente de una base de datos viva,
.dumpfunciona, pero el comando dedicado.backup(lo veremos más adelante en el curso) es más rápido y seguro, porque usa la API de backup en línea de SQLite.
Lo que viene: consultar datos
Ya tienes una visión completa de cómo escribir datos: INSERT, UPDATE, DELETE, UPSERT, RETURNING, importar desde CSV y volver a exportar. Toca la otra mitad del trabajo con una base de datos: leer datos de forma eficiente. La sentencia SELECT es donde pasarás la mayor parte del tiempo, y de eso trata la siguiente página.
Preguntas frecuentes
¿Cómo exporto una tabla de SQLite a CSV?
Desde la shell de sqlite3, cambia a modo CSV, activa las cabeceras, redirige la salida a un archivo y lanza la consulta: .mode csv, .headers on, .output users.csv y luego SELECT * FROM users;. Cuando termines, ejecuta .output stdout para volver a ver los resultados en la terminal.
¿En qué se diferencia .dump de exportar a CSV?
.dump genera un archivo .sql con las sentencias CREATE TABLE e INSERT necesarias para reconstruir la base de datos desde cero. El CSV, en cambio, solo guarda las filas de una consulta o tabla, sin esquema. Usa .dump para copias de seguridad y migraciones; usa CSV cuando quieras pasar los datos a una hoja de cálculo u otra herramienta.
¿Puedo exportar los resultados de una consulta SQLite a JSON?
Sí. Tienes dos opciones: activar .mode json en la shell y lanzar cualquier SELECT, o usar las funciones integradas json_object() y json_group_array() para construir el JSON dentro de la propia consulta. .mode json es lo más rápido para exportaciones puntuales; las funciones te dan control total sobre la estructura del resultado.