Skip to main content

Alembic autogenerate support for creation, alteration and deletion of enums

Project description

alembic-postgresql-enum

Alembic autogenerate support for creation, alteration and deletion of enums

Alembic will now automatically:

  • Create enums that currently are not in postgres schema
  • Remove/add/alter enum values
  • Reorder enum values
  • Delete unused enums from schema

If you are curious to know about analogs and reasons for this library to exist see alternatives and motivation

Usage

Install library:

pip install alembic-postgresql-enum

Add the line:

# env.py
import alembic_postgresql_enum
...

To the top of your migrations/env.py file.

Features

Creation of enum

When table is created

class MyEnum(enum.Enum):
    one = 1
    two = 2
    three = 3


class ExampleTable(BaseModel):
    test_field = Column(Integer, primary_key=True, autoincrement=False)
    enum_field = Column(postgresql.ENUM(MyEnum)) 

This code will generate migration given below:

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    # this line is generated by our library
    sa.Enum('one', 'two', 'three', name='myenum').create(op.get_bind())
    op.create_table('example_table',
    sa.Column('test_field', sa.Integer(), nullable=False),
    # create_type=False argument is now present on postgresql.ENUM as library takes care of enum creation
    sa.Column('enum_field', postgresql.ENUM('one', 'two', 'three', name='myenum', create_type=False), nullable=True),
    sa.PrimaryKeyConstraint('test_field')
    )
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    # drop_table does not drop enum by alembic
    op.drop_table('example_table')
    # It is dropped by us
    sa.Enum('one', 'two', 'three', name='myenum').drop(op.get_bind())
    # ### end Alembic commands ###

When column is added

class MyEnum(enum.Enum):
    one = 1
    two = 2
    three = 3


class ExampleTable(BaseModel):
    test_field = Column(Integer, primary_key=True, autoincrement=False)
    # this column has just been added
    enum_field = Column(postgresql.ENUM(MyEnum)) 

This code will generate migration given below:

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    # this line is generated by our library
    sa.Enum('one', 'two', 'three', name='myenum').create(op.get_bind())
    # create_type=False argument is now present on postgresql.ENUM as library takes care of enum creation
    op.add_column('example_table', sa.Column('enum_field', postgresql.ENUM('one', 'two', 'three', name='myenum', create_type=False), nullable=False))
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('example_table', 'enum_field')
    # enum is explicitly dropped as it is no longer used
    sa.Enum('one', 'two', 'three', name='myenum').drop(op.get_bind())
    # ### end Alembic commands ###

Deletion of unreferenced enum

If enum is defined in postgres schema, but its mentions removed from code - It will be automatically removed

class ExampleTable(BaseModel):
    test_field = Column(Integer, primary_key=True, autoincrement=False)
    # enum_field is removed from table
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('example_table', 'enum_field')
    sa.Enum('one', 'two', 'four', name='myenum').drop(op.get_bind())
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    sa.Enum('one', 'two', 'four', name='myenum').create(op.get_bind())
    op.add_column('example_table', sa.Column('enum_field', postgresql.ENUM('one', 'two', 'four', name='myenum', create_type=False), autoincrement=False, nullable=True))
    # ### end Alembic commands ###

Creation of new enum values

If new enum value is defined sync_enum_values function call will be added to migration to account for it

class MyEnum(enum.Enum):
    one = 1
    two = 2
    three = 3
    four = 4 # New enum value
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'three', 'four'], 
                        [('example_table', 'enum_field')],
                        enum_values_to_rename=[])
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'three'], 
                        [('example_table', 'enum_field')],
                        enum_values_to_rename=[])
    # ### end Alembic commands ###

Deletion of enums values

If enum value is removed it also will be detected

class MyEnum(enum.Enum):
    one = 1
    two = 2
    # three = 3 removed
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('public', 'myenum', ['one', 'two'], 
                        [('example_table', 'enum_field')],
                        enum_values_to_rename=[])
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'three'], 
                        [('example_table', 'enum_field')],
                        enum_values_to_rename=[])
    # ### end Alembic commands ###

Rename enum value

In this case you must manually edit migration

class MyEnum(enum.Enum):
    one = 1
    two = 2
    three = 3 # renamed from `tree`

This code will generate this migration:

def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'three'], 
                        [('example_table', 'enum_field')],
                        enum_values_to_rename=[])
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'tree'], 
                        [('example_table', 'enum_field')],
                        enum_values_to_rename=[])
    # ### end Alembic commands ###

This migration will cause problems with existing rows that references MyEnum

So adjust migration like that

def upgrade():
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'three'], 
                        [('example_table', 'enum_field')],
                        enum_values_to_rename=[('tree', 'three')])


def downgrade():
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'tree'], 
                        [('example_table', 'enum_field')],
                        enum_values_to_rename=[('three', 'tree')])

Do not forget to switch places old and new values for downgrade

All defaults in postgres will be renamed automatically as well

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

alembic_postgresql_enum-0.1.9a1.tar.gz (11.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

alembic_postgresql_enum-0.1.9a1-py3-none-any.whl (13.5 kB view details)

Uploaded Python 3

File details

Details for the file alembic_postgresql_enum-0.1.9a1.tar.gz.

File metadata

  • Download URL: alembic_postgresql_enum-0.1.9a1.tar.gz
  • Upload date:
  • Size: 11.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.5.0 CPython/3.11.0rc2 Linux/5.19.0-46-generic

File hashes

Hashes for alembic_postgresql_enum-0.1.9a1.tar.gz
Algorithm Hash digest
SHA256 5b949793afa551fb77b2eed09f815b987dabeb5f6edac15ec8cbec3a3440870d
MD5 ca59028cb46e27b45372b9949b015073
BLAKE2b-256 0621b3dc468f2466eca6d53120cd9aca5bd6b4f9d9642297f19ac301b7176428

See more details on using hashes here.

File details

Details for the file alembic_postgresql_enum-0.1.9a1-py3-none-any.whl.

File metadata

File hashes

Hashes for alembic_postgresql_enum-0.1.9a1-py3-none-any.whl
Algorithm Hash digest
SHA256 bbc1d5c89142c7519adcf649f9c180c54e3e723d74fcc4b3b8fddadf8b670287
MD5 1ab246c2aa94d94703942c17ab741a3f
BLAKE2b-256 244687c4c442a426844d68ae579ba011478e193230b8889071c8d1245ed7e3ec

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page