Metadata-Version: 2.1
Name: alembic-postgresql-enum
Version: 0.1.3
Summary: Alembic autogenerate support for creation, alteration and deletion of enums
License: MIT
Author: RustyGuard
Requires-Python: >=3.7,<4.0
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Requires-Dist: SQLAlchemy (>=1.4)
Requires-Dist: alembic (>=1.7)
Project-URL: Source code, https://github.com/RustyGuard/alembic-postgresql-enum
Description-Content-Type: text/markdown

# alembic-postgresql-enum
[<img src="https://img.shields.io/pypi/pyversions/alembic-postgresql-enum">](https://pypi.org/project/alembic-postgresql-enum/)
[<img src="https://img.shields.io/pypi/v/alembic-postgresql-enum">](https://pypi.org/project/alembic-postgresql-enum/)
[<img src="https://img.shields.io/pypi/l/alembic-postgresql-enum">](https://pypi.org/project/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

## Usage

Install library:
```
pip install alembic-postgresql-enum
```

Add the line:

```python 
# env.py
import alembic_postgresql_enum
...
```

To the top of your env.py.

## Examples

### Creation of enum
```python
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(sqlalchemy.Enum(MyEnum))
```
This code will generate migration given below: 
```python
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    sa.Enum('one', 'two', 'three', name='myenum').create(op.get_bind())
    op.add_column('example_table', sa.Column('enum_field', sa.Enum('one', 'two', 'three', name='myenum'), nullable=False))
    op.add_column('example_table', sa.Column('third_field', sa.Float(), nullable=True))
    # ### end Alembic commands ###


def downgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_column('example_table', 'third_field')
    op.drop_column('example_table', 'enum_field')
    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 - I will be automatically removed
```python
class ExampleTable(BaseModel):
    test_field = Column(Integer, primary_key=True, autoincrement=False)
    # enum_field is removed
```

```python
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'), autoincrement=False, nullable=True))
    # ### end Alembic commands ###
```

### Rename enum value
In this case you must manually edit migration

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

This code will generate this migration:
```python
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'three'], [('example_table', 'enum_field')])
    # ### 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')])
    # ### end Alembic commands ###
```

It is fine if you do not have any data in your database. 
But in most cases it is not.

So adjust migration like that

```python
def upgrade():
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'tree', 'three'], [('example_table', 'enum_field')])
    op.execute("""UPDATE example_table SET enum_field = 'three' WHERE enum_field = 'tree'""")
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'three'], [('example_table', 'enum_field')])


def downgrade():
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'tree', 'three'], [('example_table', 'enum_field')])
    op.execute("""UPDATE example_table SET enum_field = 'tree' WHERE enum_field = 'three'""")
    op.sync_enum_values('public', 'myenum', ['one', 'two', 'tree'], [('example_table', 'enum_field')])
```

Expand old values with new one, update all old values with new one, remove old enum value 
