← Весь справочник

sqlite3

Консольный клиент SQLite — база в одном файле, SQL-запросы и служебные dot-команды

sqlite3 открывает базу SQLite — обычный файл на диске — и выполняет SQL. Сервер не нужен: запрос можно передать аргументом, через stdin или ввести в интерактивной консоли. Кроме SQL клиент понимает служебные команды, начинающиеся с точки.

Синтаксис

sqlite3 [опции] [файл.db] ["SQL или .команда" …]

Без запросов после имени файла открывается интерактивная консоль (выход — .quit или Ctrl+D). Каждый следующий аргумент выполняется по очереди, как отдельная строка ввода. Без имени файла база создаётся в памяти и пропадает при выходе.

Опции командной строки

Формат вывода

ОпцияЧто делает
-listзначения через разделитель (по умолчанию |) — режим по умолчанию
-csvCSV с кавычками там, где нужно
-column, -table, -box, -markdownвыровненная таблица: без рамки / ASCII-рамка / рамка псевдографикой / Markdown
-json, -line, -tabs, -html, -quoteJSON-массив, «колонка = значение» построчно, TSV, HTML, SQL-литералы
-header / -noheaderпечатать / не печатать имена колонок
-separator SEPразделитель колонок для -list
-nullvalue TEXTчем показывать NULL (по умолчанию — пустая строка)

Поведение

ОпцияЧто делает
-cmd '.команда'выполнить команду до основных запросов — удобно задать режим
-bailостановиться на первой ошибке
-readonlyоткрыть базу только на чтение
-echoпечатать каждый запрос перед выполнением
-init файлвыполнить файл при старте вместо ~/.sqliterc
-batchнеинтерактивный режим, даже если ввод — терминал
-versionверсия SQLite

Dot-команды

Структура базы

КомандаЧто делает
.tables [шаблон]список таблиц и представлений (шаблон — как в LIKE: user%)
.schema [шаблон]CREATE-операторы таблиц, индексов, триггеров
.indexes [таблица]имена индексов
.databasesподключённые базы и их файлы (main, базы из ATTACH)
.showтекущие настройки клиента: режим, заголовки, разделитель

Вывод

КомандаЧто делает
.mode РЕЖИМlist, csv, column, table, box, markdown, json, line, tabs, html, quote, insert ТАБЛИЦА
.headers on|offзаголовки колонок
.separator COL [ROW]разделитель колонок (и строк)
.nullvalue TEXTотображение NULL
.width N1 N2 …ширина колонок для column/table/box
.output файл / .outputвесь дальнейший вывод в файл / обратно на экран
.once файлв файл — только результат следующего запроса
.print текстнапечатать строку

Данные и файлы

КомандаЧто делает
.import [опции] файл таблицазагрузить файл в таблицу; без --csv разделитель берётся из текущего .mode
.import --csvразобрать как CSV (кавычки, запятые внутри полей)
.import --skip Nпропустить первые N строк — обычно строку заголовка
.read файл.sqlвыполнить SQL из файла
.dump [таблица]выгрузить базу или таблицу как SQL (CREATE + INSERT)
.backup файл / .restore файлкопия базы в файл / восстановление из копии
.open файлзакрыть текущую базу и открыть другую
.shell командавыполнить команду оболочки
.help [команда]справка; .help import — подробно об одной команде
.quit / .exit [код]выход (с кодом возврата)

Dot-команда занимает целую строку и пишется без ; в конце.

Полезный SQL в SQLite

ЗапросЧто делает
PRAGMA table_info(t)колонки таблицы: имя, тип, NOT NULL, значение по умолчанию, PK
SELECT name FROM sqlite_master WHERE type='table'таблицы через SQL
typeof(x)фактический тип значения: integer, real, text, blob, null
CREATE TABLE t2 AS SELECT …таблица из результата запроса
INSERT OR REPLACE INTO …вставить или заменить строку при конфликте ключа
INSERT … ON CONFLICT(k) DO UPDATE SET v = excluded.vupsert: обновить существующую строку
ATTACH 'other.db' AS oподключить вторую базу, таблицы — как o.таблица
BEGIN; … COMMIT; / ROLLBACK;транзакция
PRAGMA foreign_keys = ONвключить проверку внешних ключей (по умолчанию выключена)

Примеры

# создать таблицу и вставить строки (файл базы появится сам)
sqlite3 app.db "CREATE TABLE users(id INTEGER PRIMARY KEY, name TEXT);
INSERT INTO users(name) VALUES ('alice'), ('bob');"

# какие таблицы есть и как они устроены
sqlite3 app.db ".tables"
sqlite3 app.db ".schema users"
sqlite3 app.db "PRAGMA table_info(users)"

# результат с заголовками в виде таблицы
sqlite3 -header -column app.db "SELECT * FROM users"

# выгрузить результат в CSV
sqlite3 -csv -header app.db "SELECT id, name FROM users" > users.csv

# режим задаётся через -cmd, а запрос идёт следом
sqlite3 -cmd ".mode box" app.db "SELECT count(*) AS n FROM users"

# одно значение без оформления — удобно присвоить переменной
n=$(sqlite3 app.db "SELECT count(*) FROM users")

# CSV в новую таблицу: первая строка станет именами колонок
sqlite3 app.db ".import --csv data.csv data"

# CSV в существующую таблицу: строку заголовка пропускаем
sqlite3 app.db ".import --csv --skip 1 data.csv users"

# скрипт из файла; -bail остановит его на первой ошибке
sqlite3 -bail app.db < queries.sql

# полная выгрузка в SQL и восстановление в другую базу
sqlite3 app.db .dump > dump.sql
sqlite3 copy.db < dump.sql

# только чтение — защитит от случайного UPDATE
sqlite3 -readonly app.db "SELECT * FROM users"

Несколько команд подряд удобно передать через heredoc:

sqlite3 app.db <<'EOF'
.headers on
.mode csv
.output report.csv
SELECT * FROM users;
.output
EOF

Подводные камни

  • Опечатка в имени файла создаёт новую пустую базу. sqlite3 ap.db ".tables" ничего не покажет и оставит пустой ap.db. Если таблиц «нет», сначала проверь путь. А sqlite3 "SELECT 1" без имени базы молча создаст файл с именем SELECT 1: первый аргумент всегда считается файлом.
  • Строки — в одинарных кавычках. WHERE name = "bob" сработает, только пока нет колонки bob: двойные кавычки означают имя колонки, а в строку SQLite превращает их лишь по старой совместимости. Пиши 'bob'.
  • .import в новую таблицу делает все колонки TEXT. Сравнения и сортировка чисел станут строковыми ('10' < '9'). Создай таблицу с нужными типами заранее и импортируй в неё с --skip 1.
  • .import в существующую таблицу без --skip 1 загрузит строку заголовка как обычную строку данных.
  • .import без --csv делит строки по разделителю текущего режима (| в list) и не понимает кавычки. Для CSV всегда указывай --csv.
  • Типы в SQLite мягкие. Колонка INTEGER примет строку 'abc', ошибки не будет. Проверяй через typeof().
  • Внешние ключи по умолчанию не проверяются. REFERENCES в схеме без PRAGMA foreign_keys = ON (в каждом подключении) ничего не гарантирует.
  • В оболочке SQL бери в двойные кавычки целиком, а строковые литералы внутри — в одинарные. Иначе bash съест кавычки до того, как запрос дойдёт до sqlite3.
  • Скрипт из stdin после ошибки идёт дальше: следующие строки выполнятся, и только код возврата будет 1. Чтобы остановиться на первой ошибке, добавь -bail.
  • .output файл действует до отмены. Забытый .output без аргумента отправит в файл и всё последующее. Для одного запроса удобнее .once.

См. также

psql · redirection · cut · datamash