sqlite3, one command per page
Twenty-nine commands for the shell that runs a database out of a single file: how the dot commands differ from SQL, the semicolon that ends a statement and the continuation prompt when you forget it, box and csv modes, importing CSV with headers skipped and tables auto-created, exporting with .once, the .dump you can pipe straight back in, opening read-only, cross-database queries with ATTACH, and the PRAGMA checks that keep a file honest.
A diagram, the command, and one thing to go run this week. That's a page.
sqlite3, one command per page
Twenty-nine commands for the shell that runs a database out of a single file: how the dot commands differ from SQL, the semicolon that ends a statement and the continuation prompt when you forget it, box and csv modes, importing CSV with headers skipped and tables auto-created, exporting with .once, the .dump you can pipe straight back in, opening read-only, cross-database queries with ATTACH, and the PRAGMA checks that keep a file honest.
Set in Space Grotesk, Inter and JetBrains Mono (SIL Open Font License).
Every command, rule, default and version gate in this book is as the official sources state it, fetched and read during this build: the SQLite documentation at sqlite.org (Command Line Shell For SQLite, updated 2026-08-14, dot-command list as shown for version 3.52.0; Query Language Understood by SQLite; Pragma Statements Supported by SQLite; Appropriate Uses For SQLite; Most Widely Deployed SQL Database Engine). Demand evidence from live beginner threads and recurring guide popularity, fetched this build; no facts are sourced from Reddit. Teaching conventions (one command a page) are named as conventions.
Your purchase is for personal use only. You do not have redistribution rights: please do not share, resell, or republish this book or its pages.
General information only. Not professional advice; check behaviours against your own sqlite3 version, which may differ.
© 2026 Steve Hodgkiss. All rights reserved. Personal use only; no redistribution rights.
Edition 1.0 · stevehodgkiss.net
Contents
Open
What SQLite is, how the sqlite3 command both opens and creates a database file, the transient in-memory database, and the two grammars inside one prompt: SQL that ends in a semicolon and dot-commands that don't.
- 01One file, no server
- 02The dot is the shell
Per sqlite.org, Appropriate Uses For SQLite: SQLite is not directly comparable to client/server SQL database engines such as MySQL, Oracle, PostgreSQL or SQL Server since it is trying to solve a different problem; client/server engines emphasize scalability, concurrency, centralization and control; SQLite strives to provide local data storage for individual applications and devices; SQLite competes with fopen(); per Most Widely Deployed SQL Database Engine: SQLite is likely used more than all other database engines combined and is found in every Android device, every iPhone, every Mac, every Windows 10/11 installation and every Firefox, Chrome and Safari browser.
One file, no server
A MySQL or Postgres database lives in a server process you install, start and log in to over the network. SQLite's whole database is one ordinary file on disk, and the docs put it best: SQLite competes with fopen(). No daemon, no port, no password.
That's why it's everywhere. The sqlite.org pages say it's found in every Android device, every iPhone, every Mac, every Windows 10/11 install and every major browser, more than all other database engines combined. You have been carrying these files for years.
To read one you don't set up a server. You open the file.
Search your home directory for .db and .sqlite files today. Most machines hold dozens you never knew about.
Per sqlite.org, Command Line Shell For SQLite, Special commands (dot-commands): input lines that begin with a dot are intercepted and interpreted by the sqlite3 program itself; they are typically used to change the output format of queries or to execute certain prepackaged query statements; there are over 60 dot commands; dot-commands must begin with the dot at the left margin with no preceding whitespace and must be entirely contained on a single input line; dot-commands cannot occur in the middle of an ordinary SQL statement; there is no comment syntax for dot-commands; dot-commands are interpreted by the command-line program, not by the SQLite library, so they will not work as an argument to core library interfaces such as sqlite3_exec().
The dot is the shell
Two languages share the sqlite> prompt. Lines that start with a dot are intercepted by the sqlite3 program itself. Lines that don't go to the SQLite library as SQL.
Dot-commands have their own rules: they must start at the left margin, sit on one line, and they take no semicolon. There are over 60 of them. They're shell settings and shortcuts, which is why they'd never work inside sqlite3_exec() in your code.
SQL ends in a semicolon. Dot-commands are one line, no semicolon, no indent. That's the whole split.
Type a space before .tables and watch it fail as SQL. Left margin means left margin.
Move
The import and export workflows every beginner lands on: .read for SQL files, .import for CSV with its header and auto-create rules, .once and .output for files and pipes, and .dump as the archival format you can pipe straight back in.
- 01Import CSV
- 02Export to CSV
- 03Dump and rebuild
Per sqlite.org, Command Line Shell For SQLite, Importing files as CSV or other formats: the .import command takes two arguments, the source to read from and the name of the SQLite table to insert into; the source is a file, or if it begins with | a command that produces the input; it may be important to set the mode before running .import, or use --csv or --ascii which control the import delimiters; in modes other than ascii, .import interprets input as records composed of fields according to the RFC 4180 specification; example: .import --csv --skip 1 --schema temp C:/work/somedata.csv tab1.
Import CSV
.import --csv data.csv tab1 reads the file into the table. The parsing follows RFC 4180, so quoted fields with commas inside come through correctly. The source can even be a command: start it with | and its output becomes the input.
Set the mode or pass --csv explicitly; without it the delimiters in force for the current output mode are used, and that's how a csv file lands mangled. The exact example from the docs, with headers skipped, is next page.
This one command is the answer to the internet's most-asked sqlite question.
Take any CSV you have, run .mode csv then .import --csv thatfile.csv t, and .schema t to see what arrived.
Per sqlite.org, Command Line Shell For SQLite, Export to CSV: to export an SQLite table or part of a table as CSV, set the mode to csv and run a query to extract the desired rows; the output will be formatted as CSV per RFC 4180; .mode csv --titles on causes column labels to be printed as the first row of output (--titles off is the default); the .once FILENAME line causes query output to go into the named file; example session: .mode csv --titles on, .once c:/work/dataout.csv, SELECT * FROM tab1;.
Export to CSV
The docs' export is three lines. .mode csv --titles on, so the first row carries column labels, .once dataout.csv, then the query. Output is CSV per RFC 4180, quoting and all, so it opens clean anywhere.
Any query exports, not just a whole table: add WHERE and you've exported a slice. When it's done, .mode box brings the screen back to human shape.
Import on page 13, export here. Round-tripping CSV is most of what people do with this shell.
Export the table you imported earlier with the three-line recipe, then open the file and check the header row.
Per sqlite.org, Command Line Shell For SQLite, Converting An Entire Database To A Text File: use the .dump command to convert the entire contents of a database into a single UTF-8 text file; this file can be converted back into a database by piping it back into sqlite3; a good way to make an archival copy is sqlite3 ex1 .dump | gzip -c >ex1.dump.gz; to reconstruct the database, zcat ex1.dump.gz | sqlite3 ex2; the text format is pure SQL so the .dump output can also be piped into other popular SQL database engines.
Dump and rebuild
.dump renders the whole database as one UTF-8 text file of pure SQL. Pipe it back into sqlite3 and you have the database again, on this machine or another.
The docs' archival recipe, verbatim: sqlite3 ex1 .dump | gzip -c >ex1.dump.gz, rebuilt with zcat ex1.dump.gz | sqlite3 ex2. And because the format is pure SQL, the same stream feeds other SQL engines.
A backup you can read with your eyes and restore with a pipe. That's .dump.
Dump a scratch database, gzip it, delete the original, rebuild from the dump. Time the whole loop.
Per sqlite.org, Command Line Shell For SQLite, Getting Started: .open with the --readonly option opens the database in read-only mode, writes will be prohibited; per the --safe option list and Opening Database Files: the --ifexists option makes .open only work if the database file already exists, preventing a new, empty database from being created; per Command-line Options, -readonly opens the database read-only.
Open it read-only
Point sqlite3 at a file you must not change and read mode matters. .open --readonly ex1.db opens it with writes prohibited, and sqlite3 -readonly ex1.db does it from launch.
Pair it with --ifexists, which refuses to open a file that isn't there, the opposite of page 2's auto-create. On a file that matters, that pair removes both ways to damage it by accident.
An empty ex1.db sitting sadly next to a typo'd ex1d.db is the memorial of a missing --ifexists.
Copy a real .db file somewhere safe, open it with -readonly, and try an UPDATE. Watch it refuse.