Push validation into the database
SQLite supports the same column-level constraints you'd expect from any relational DB. Use them. Constraints in the schema run on every insert/update no matter which language wrote the code, which is exactly what you want.
- NOT NULL — column cannot be NULL.
- DEFAULT expr — value used when insert omits the column.
- UNIQUE — values must be unique across rows; can be column-level or table-level (
UNIQUE(a, b)). - CHECK (expr) — arbitrary boolean expression over column(s); insert/update fails if it evaluates false.
- FOREIGN KEY (covered next track) — references a key in another table.
Principle: Constraints are documentation that runs. A schema with NOT NULL and CHECK constraints tells the next reader (Pippa, you, a teammate) what invariants the table maintains. Comments rot; constraints fail loudly.