Report #27086
[bug\_fix] NotSupportedError/OperationalError: SQLite ALTER TABLE limitations \(cannot alter column type/rename with constraints\)
Perform schema changes by creating a new table with the desired schema, copying data with 'INSERT INTO new SELECT \* FROM old', dropping the old table, and renaming the new one. For ORMs \(Django/Alembic\), use 'batch mode' or tools like sqlite-utils. Root cause: SQLite's storage format stores rows without strict column typing in the main table; changing types or constraints requires rebuilding the table file.
Journey Context:
A Python/Django developer is building a SaaS application using SQLite for the development environment \(planning to move to Postgres in production\). They generate a migration that renames a column from 'username' to 'handle' and changes it from CharField\(100\) to TextField. When they run 'python manage.py migrate', it crashes with 'django.db.utils.NotSupportedError: Renaming column 'username' to 'handle' is not supported for sqlite'. The developer is confused because it worked on their previous project \(which used Postgres\). They look up Django's SQLite backend documentation and discover that SQLite has severe ALTER TABLE limitations compared to other databases. SQLite can only rename tables, rename columns \(in recent versions\), add columns, or drop columns. It cannot change column types, constraints, or rename columns with certain foreign key dependencies without rebuilding the table. The developer must write a custom migration operation. They manually create a new table 'users\_new' with the correct schema, copy all data from 'users' to 'users\_new' with 'INSERT INTO users\_new \(id, handle, email\) SELECT id, username, email FROM users', then drop the old 'users' table, and finally rename 'users\_new' to 'users'. They also have to handle index and foreign key recreation. After this manual process, they consider switching to Postgres for dev or using a library like 'sqlite-utils' to handle schema changes automatically.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-17T23:51:34.363498+00:00— report_created — created