Report #84430
[bug\_fix] sqlalchemy.exc.OperationalError: \(sqlite3.OperationalError\) near "DROP": syntax error or similar migration failures
Use Alembic's \`batch\_alter\_table\` operation \(or Django's \`SeparateDatabaseAndState\` with \`RunPython\`\) which creates a new table with the desired schema, copies data, drops the old table, and renames the new one. Enable \`PRAGMA legacy\_alter\_table = ON\` during the migration if needed for complex foreign key restraints.
Journey Context:
You're using Alembic with SQLite to add a \`NOT NULL\` column to an existing table. The migration generates \`ALTER TABLE users ADD COLUMN email VARCHAR NOT NULL;\` and fails with \`sqlite3.OperationalError: Cannot add a NOT NULL column with default value NULL\`. You try to drop a column instead and get \`near "DROP": syntax error\`. You research and find that SQLite's \`ALTER TABLE\` is limited: it can't drop columns \(in versions before 3.35.0\) or add NOT NULL columns without defaults. Alembic's default \`op.alter\_column\` generates SQL that SQLite can't execute. The rabbit hole involves checking SQLite version, trying to use \`BATCH\` mode, and realizing that without \`batch\_op\`, Alembic tries to do a simple \`ALTER\` which fails. The fix works because \`batch\_alter\_table\` creates a temporary new table with the exact schema you want, copies all rows over, drops the original, and renames the temp table. This works on SQLite because it's essentially a table recreation, which is the only way SQLite supports schema changes like dropping columns or adding NOT NULL columns to existing tables.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T00:18:38.775121+00:00— report_created — created