Alembic PostgreSQL Enum
alembic-postgresql-enum provides autogenerate support for the creation, alteration, and deletion of PostgreSQL enums within Alembic migration scripts. It addresses limitations where Alembic's default autogenerate often fails to detect and generate migrations for enum value changes (like deletions or reordering). The library is actively maintained, with the latest version 1.10.0 released in February 2026.
Warnings
- gotcha For `alembic-postgresql-enum` to automatically detect enum changes and generate migrations, you *must* include `import alembic_postgresql_enum` at the very top of your `migrations/env.py` file.
- gotcha When modifying enum values (especially deleting or renaming), be aware that PostgreSQL's `ALTER TYPE` statements for enums have specific transactional limitations. Historically, `ALTER TYPE ... ADD VALUE` cannot be used until the transaction is committed, which can lead to issues if not handled correctly. `alembic-postgresql-enum` attempts to manage this, but manual SQL operations might still encounter it.
- gotcha By default, the order of enum values matters in PostgreSQL. If `alembic-postgresql-enum` detects a reordering of values, it will generate a migration. If you wish to ignore changes in enum value order, you can set the `ignore_enum_values_order` flag to `True` in your configuration.
- gotcha PostgreSQL ENUM types created via raw SQL statements (`op.execute("CREATE TYPE ...")`) without explicit schema qualification can end up in the `public` schema, even if tables and other objects respect a configured schema. While `alembic-postgresql-enum` aims to manage enums properly, ensure your setup (especially if mixing with raw SQL) correctly applies schema to enums.
Install
-
pip install alembic-postgresql-enum
Imports
- alembic_postgresql_enum
import alembic_postgresql_enum
- EnumMigration
from alembic_postgresql_enum import EnumMigration
- Column
from alembic_postgresql_enum import Column
Quickstart
import os
import enum
from sqlalchemy import Column, Integer
from sqlalchemy.dialects import postgresql
from sqlalchemy.orm import declarative_base
# This is a simplified example. In a real Alembic setup,
# you would define your models and then run 'alembic revision --autogenerate'
# after importing alembic_postgresql_enum in env.py
Base = declarative_base()
class ResourceState(enum.Enum):
ACTIVE = 'active'
INACTIVE = 'inactive'
ARCHIVED = 'archived'
class Resource(Base):
__tablename__ = 'resources'
id = Column(Integer, primary_key=True)
state = Column(postgresql.ENUM(ResourceState, name='resource_state'), nullable=False)
# To simulate a change for autogeneration (e.g., adding a new enum value):
# 1. Initially define ResourceState with just ACTIVE and INACTIVE.
# 2. Run alembic revision --autogenerate. A migration will be created for the initial enum.
# 3. Add 'ARCHIVED' to ResourceState (as shown above).
# 4. Ensure 'import alembic_postgresql_enum' is at the top of your migrations/env.py.
# 5. Run alembic revision --autogenerate again.
# The library should now generate an 'op.sync_enum_values' call to add 'ARCHIVED'.
print("Alembic-PostgreSQL-Enum quickstart concept: Define your SQLAlchemy models with PostgreSQL ENUMs.")
print("Ensure 'import alembic_postgresql_enum' is added to your migrations/env.py.")
print("Modify your enum definition (add, remove, rename values), then run 'alembic revision --autogenerate'.")
print("The library will generate the necessary SQL for enum synchronization.")