Table rebuild with foreign keys still enforced
Warning — it works, but holds the single write lock or breaks the previous release.
What it catches
This migration rebuilds a table the documented way — create the new table, copy, drop the old, rename — but never turns foreign keys off first. With PRAGMA foreign_keys=ON the DROP TABLE performs an implicit DELETE FROM: rows referencing the table fail the migration with a constraint error, or ON DELETE CASCADE quietly removes them.
Fires on
CREATE TABLE orders_new (id INTEGER PRIMARY KEY, qty INTEGER NOT NULL);
INSERT INTO orders_new SELECT id, qty FROM orders;
DROP TABLE orders;
ALTER TABLE orders_new RENAME TO orders;Do this instead
Follow the twelve steps from the SQLite manual: PRAGMA foreign_keys=OFF outside the transaction, rebuild inside it, PRAGMA foreign_key_check before COMMIT, and PRAGMA foreign_keys=ON after.
PRAGMA foreign_keys = OFF;
BEGIN;
CREATE TABLE orders_new (id INTEGER PRIMARY KEY, qty INTEGER NOT NULL);
INSERT INTO orders_new SELECT id, qty FROM orders;
DROP TABLE orders;
ALTER TABLE orders_new RENAME TO orders;
PRAGMA foreign_key_check;
COMMIT;
PRAGMA foreign_keys = ON; SQLite support is in alpha: this rule runs locally in the free CLI, static only, and not in the hosted service yet: npx bolvrk check migration.sql --engine=sqlite