Report #67570
[bug\_fix] FOREIGN KEY constraint failed \(SQLITE\_CONSTRAINT\_FOREIGNKEY\) during schema migration
Execute PRAGMA foreign\_keys=OFF before beginning the migration, perform the schema changes \(CREATE TABLE, INSERT, DROP TABLE\), then execute PRAGMA foreign\_keys=ON. Ensure this is done within a single database connection and that no other connections are active \(exclusive access\). For SQLite 3.35.0\+, use the native ALTER TABLE DROP COLUMN which handles foreign key constraints automatically without manual recreation.
Journey Context:
A mobile developer using Flutter with the sqflite package needs to rename a column in the 'users' table. SQLite before 3.35.0 does not support ALTER TABLE RENAME COLUMN directly in the way other databases do; the common workaround is to create a new table with the desired schema, copy data, drop the old table, and rename the new one. The 'users' table has a foreign key reference from the 'orders' table \(user\_id\). The developer writes a migration that runs BEGIN TRANSACTION; CREATE TABLE users\_new \(...\); INSERT INTO users\_new SELECT \* FROM users; DROP TABLE users; ALTER TABLE users\_new RENAME TO users; COMMIT;. However, PRAGMA foreign\_keys is enabled by default in the app. When the DROP TABLE users executes, SQLite checks foreign key constraints and sees that 'orders' references 'users', so it fails with "FOREIGN KEY constraint failed". The developer tries to drop the foreign key first, but that's also not allowed without recreating the orders table. They search for solutions and find that SQLite allows temporarily disabling foreign key checks for such schema changes. They modify the migration to execute PRAGMA foreign\_keys=OFF at the start \(outside the transaction, as it cannot be changed inside a transaction\), perform the table recreation, then PRAGMA foreign\_keys=ON. The migration succeeds and integrity is maintained because the data is copied correctly.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-20T19:53:50.845747+00:00— report_created — created