
Imagen: fancycrave1 / Pixabay
Para migrar una base de datos SQLite sin perder información, haz primero una copia de seguridad, controla la versión del esquema con PRAGMA user_version y aplica cada cambio dentro de una transacción; para optimizarla en una aplicación web, activa el modo WAL, crea índices para las consultas frecuentes, revisa los planes de ejecución con EXPLAIN QUERY PLAN y ejecuta PRAGMA optimize periódicamente. Esta guía te lleva por cada paso con ejemplos.
¿Cuándo es buena idea usar SQLite en la web?
SQLite guarda toda la base de datos en un archivo y no requiere un servidor aparte, lo que la hace ideal para aplicaciones pequeñas y medianas, prototipos, herramientas internas y microaplicaciones con más lecturas que escrituras. Si tu aplicación tendrá muchas escrituras simultáneas desde varios servidores, conviene evaluar un motor cliente-servidor como PostgreSQL o MySQL.
Paso 1. Haz una copia de seguridad antes de tocar nada
No copies el archivo mientras la aplicación escribe en él. Usa una copia consistente:
sqlite3 app.db "VACUUM INTO 'respaldo-2026-10-15.db'"VACUUM INTO (disponible desde SQLite 3.27) crea una copia compacta y consistente. Otra opción es el comando .backup de la consola de sqlite3.
Paso 2. Versiona el esquema con user_version
SQLite reserva un número entero en la cabecera del archivo que puedes usar como versión del esquema:
PRAGMA user_version; -- consulta la versión actual (0 por defecto)
PRAGMA user_version = 3; -- la actualizaTu aplicación, al iniciar, compara esa versión con la última migración disponible y aplica solo las que faltan.
Paso 3. Aplica cada migración dentro de una transacción
BEGIN;
ALTER TABLE clientes ADD COLUMN telefono TEXT;
CREATE INDEX IF NOT EXISTS idx_clientes_telefono ON clientes(telefono);
PRAGMA user_version = 4;
COMMIT;Si algo falla, ejecuta ROLLBACK y la base queda como estaba.
Paso 4. Cambios que ALTER TABLE no permite directamente
ALTER TABLE en SQLite permite renombrar tablas y columnas, añadir columnas y, en versiones recientes, eliminar columnas con ciertas condiciones. Para cambios más profundos (cambiar el tipo de una columna o sus restricciones), la documentación oficial recomienda reconstruir la tabla:
- Desactiva temporalmente las claves foráneas:
PRAGMA foreign_keys = OFF; - Inicia una transacción.
- Crea la tabla nueva con el esquema correcto (por ejemplo,
clientes_nueva). - Copia los datos:
INSERT INTO clientes_nueva (...) SELECT ... FROM clientes; - Elimina la tabla vieja y renombra la nueva.
- Vuelve a crear índices, disparadores y vistas.
- Comprueba la integridad:
PRAGMA foreign_key_check; - Confirma la transacción y reactiva
PRAGMA foreign_keys = ON;
Paso 5. Configura SQLite para una aplicación web
Al abrir cada conexión, estas instrucciones suelen mejorar el comportamiento en la web:
PRAGMA journal_mode = WAL; -- lectores y escritor pueden trabajar a la vez
PRAGMA synchronous = NORMAL; -- buen equilibrio entre seguridad y velocidad en modo WAL
PRAGMA foreign_keys = ON; -- SQLite no las aplica si no las activas
PRAGMA busy_timeout = 5000; -- espera hasta 5 s si la base está ocupadaSegún la documentación de SQLite, el modo WAL permite que las lecturas no bloqueen a la escritura y viceversa, aunque sigue habiendo un solo escritor a la vez. El modo WAL se guarda en el archivo; las demás opciones deben aplicarse en cada conexión.
Paso 6. Crea los índices correctos
Revisa cómo resuelve SQLite tus consultas más frecuentes:
EXPLAIN QUERY PLAN
SELECT * FROM pedidos WHERE cliente_id = 25 ORDER BY fecha DESC;Si el resultado indica SCAN pedidos, SQLite está recorriendo toda la tabla. Un índice compuesto puede resolverlo:
CREATE INDEX idx_pedidos_cliente_fecha ON pedidos(cliente_id, fecha);Tras crearlo, el plan debería mostrar SEARCH ... USING INDEX. No crees índices para todo: cada índice ocupa espacio y hace más lentas las escrituras.
Paso 7. Mantenimiento periódico
PRAGMA optimize;antes de cerrar conexiones de larga duración o de forma periódica, para que SQLite actualice sus estadísticas cuando lo considere útil.VACUUM;de vez en cuando para recuperar espacio tras borrar muchos datos (bloquea la base mientras se ejecuta).PRAGMA integrity_check;para detectar corrupción.- Copias de seguridad automáticas diarias, guardadas fuera del servidor.
Paso 8. Buenas prácticas en el código
- Usa consultas parametrizadas para evitar inyección SQL.
- Agrupa muchas inserciones en una sola transacción: es mucho más rápido que confirmar una por una.
- Reutiliza la conexión en lugar de abrir y cerrar una por cada petición.
- No guardes el archivo de la base en una carpeta pública del servidor web.
Preguntas frecuentes
¿Puedo usar SQLite en un hosting compartido?
Sí, si el lenguaje de tu aplicación (PHP, Node.js o Python) tiene la extensión de SQLite y la carpeta del archivo tiene permisos de escritura. Evita sistemas de archivos en red, que pueden causar problemas de bloqueo.
¿WAL crea archivos adicionales?
Sí, aparecen los archivos -wal y -shm junto a la base. Son normales y no deben borrarse mientras la aplicación está en uso.
Conclusión
Con copias de seguridad, migraciones versionadas en transacciones, modo WAL e índices bien elegidos, SQLite puede sostener con soltura muchas aplicaciones web pequeñas y medianas. Si además conectas tu aplicación con WordPress, revisa nuestra guía de la API REST de WordPress.
Fuentes consultadas
- SQLite: Write-Ahead Logging.
- SQLite: ALTER TABLE y procedimiento para otros cambios de esquema.
- SQLite: PRAGMA statements.
- SQLite: VACUUM y VACUUM INTO.
- SQLite: EXPLAIN QUERY PLAN.
Actualizado: 15 de octubre de 2026.






