Report #8011
[bug\_fix] ALTER TYPE ... ADD cannot run inside a transaction block
Disable the transaction wrapper for the specific migration. In Django, set atomic = False inside the Migration class. In Ruby on Rails, add disable\_ddl\_transaction\! inside the migration. For raw SQL execution, ensure autocommit is enabled \(no explicit BEGIN block\). This allows non-transactional commands like ALTER TYPE ... ADD VALUE or CREATE INDEX CONCURRENTLY to execute.
Journey Context:
Created a Django migration to add a new value to a CharField with choices, which translates to ALTER TYPE ... ADD VALUE in PostgreSQL. Running python manage.py migrate failed immediately with 'cannot run inside a transaction block'. Investigated: Django wraps migrations in BEGIN...COMMIT by default for atomicity. PostgreSQL explicitly forbids certain DDL commands \(ALTER TYPE ... ADD VALUE, CREATE INDEX CONCURRENTLY, VACUUM, REINDEX CONCURRENTLY\) inside transaction blocks. The rabbit hole: considered manually applying the SQL with psql and faking the migration, but that breaks migration consistency. The fix: Django 1.5\+ provides an atomic = False class attribute in the Migration class to disable the transaction wrapper. Adding atomic = False allowed the ALTER TYPE command to execute in autocommit mode, satisfying PostgreSQL's requirement. Why the fix works: It removes the BEGIN wrapper, executing the DDL statement in its own implicit transaction \(autocommit\), which is the only context where these specific PostgreSQL commands are permitted.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-16T04:18:34.107257+00:00— report_created — created