Databases
August 18, 2026 Β· View on GitHub
π·πΊ ΠΡΠ° ΡΡΡΠ°Π½ΠΈΡΠ° Π½Π° ΡΡΡΡΠΊΠΎΠΌ Β· β Documentation index
SQLite and DuckDB are the two formats tuitab does not merely read. A table opened from one can be edited and written back into the same file β and tuitab shows every statement it is about to run before a single one of them does.

Open a table
tuitab shop.sqlite
tuitab warehouse.duckdb
tuitab app.db # which engine it is comes from the file's own header
The first screen is the database's own contents β every table and view, with its
row and column counts. Enter opens the highlighted one; Esc / q goes back.
The title bar then reads shop.sqlite :: orders, and [*] appears next to it as
soon as something is unsaved.
A view opens read-only. So does the overview itself: saving either onto the
database it came from is refused, with This table or view is read-only; save to a different file instead.
Edit
Everything that works on an ordinary sheet works here: e edits a cell, ge
sets one value on every selected row, d deletes selected rows, P pastes rows,
o adds a blank one and O opens a form checked against
the column types. Columns take zi (insert), zd (delete), ze (rename), t
(change type), and z + β / β to reorder.
NULL is visible and typable. A NULL cell shows as NULL in italics rather
than as a blank, and typing \N into a cell on a database sheet writes a real
NULL. An empty string stays an empty string.
Save it back
Ctrl+S prefills the path the table came from. Confirm it and nothing is written
yet β a popup opens with the exact SQL:
β shop.sqlite β orders Β· 1 UPDATE ββββββββββββββββββββββββββ
β UPDATE "orders" SET "qty" = 12 WHERE "rowid" = 1 β
β β
β ββ Β· PgUp/PgDn Β· g/G Β· Enter run Β· Esc cancel β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Scroll it with β β, PgUp / PgDn and g / G. Enter runs the whole
list in one transaction; Esc cancels and nothing happens. The rest of the
database β other tables, indexes, views, triggers β is untouched either way.
Structural changes appear as ALTER TABLE statements in the same list:
ALTER TABLE "orders" DROP COLUMN "note", grouped under a SCHEMA heading.
When the table has to be rebuilt
Neither engine can reorder columns, and SQLite has no ALTER COLUMN, so
reordering columns β or changing a column's type on SQLite β means the table is
dropped and created again with its rows copied across. The popup says so before
you confirm:
-- this table will be rebuilt: dropped and created again, with its rows copied
A rebuild reproduces the column names, types, NOT NULL, DEFAULT and a
single-column primary key. Anything it could not carry across intact β a CHECK,
a UNIQUE, a foreign key, a collation β is a refusal rather than a silent loss:
'orders' has to be rebuilt to do this, and tuitab will not rebuild it: β¦. Save
to a different file instead.
Saving somewhere else
Point Ctrl+S at a different .db and tuitab copies the whole database
first β every table, index, view and trigger β then applies your changes to the
copy. The original is left exactly as it was. The destination has to be a file
that does not exist yet; an existing one is refused with β¦ already exists. Saving a database elsewhere writes a fresh copy of the whole file β remove it first or choose another name.
Derived sheets add a table, they do not edit one
A pivot, a JOIN result, a frequency table or a Describe sheet has no table behind it. Saving one onto a database asks for a table name and creates that table; the tables already in the file are not touched. This is also how you park a result next to the data it came from.
Build a database from nothing
Point tuitab at a database file that does not exist and it opens a blank sheet β
the title reads inventory.sqlite [new]:
tuitab inventory.sqlite
ziinserts a column and asks for its name; repeat for the rest.tgives each one a type β Integer, Float, Date, Boolean, Currency and so on.oadds a blank row, orOopens the form, which labels every field with its column's type and refuses a value the column cannot hold.Ctrl+S, then a name for the table.
What lands on disk is a real typed table: an Integer column is declared INTEGER
and stores integers, a NULL stays NULL. SQLite and DuckDB both.
See also
- Getting started β opening files and formats.
- Recipes β editing, clipboard, export.
- MCP server β letting an assistant change a table, behind a flag and a two-step handshake.