sqlite3
Консольный клиент SQLite — база в одном файле, SQL-запросы и служебные dot-команды
sqlite3 открывает базу SQLite — обычный файл на диске — и выполняет SQL. Сервер не нужен: запрос можно передать аргументом, через stdin или ввести в интерактивной консоли. Кроме SQL клиент понимает служебные команды, начинающиеся с точки.
Синтаксис
sqlite3 [опции] [файл.db] ["SQL или .команда" …]
Без запросов после имени файла открывается интерактивная консоль (выход — .quit или Ctrl+D). Каждый следующий аргумент выполняется по очереди, как отдельная строка ввода. Без имени файла база создаётся в памяти и пропадает при выходе.
Опции командной строки
Формат вывода
| Опция | Что делает |
|---|---|
-list | значения через разделитель (по умолчанию |) — режим по умолчанию |
-csv | CSV с кавычками там, где нужно |
-column, -table, -box, -markdown | выровненная таблица: без рамки / ASCII-рамка / рамка псевдографикой / Markdown |
-json, -line, -tabs, -html, -quote | JSON-массив, «колонка = значение» построчно, 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.v | upsert: обновить существующую строку |
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