Pogchamp-company/alembic-postgresql-enum

Migrating Changes Fails when updating a enum using a schema

Closed this issue · 0 comments

Thank you for your project, this has been a great help so far but we ran into a problem when trying to update the elements in the enum. The schema name in this example is enum but it happens with other schema names also.

Below are the two migration scripts to show the issue. The first creates the base environment and the second attempts to add a new element to the Status enum.

"""create base migration

Revision ID: 9e1519a34b14
Revises:
Create Date: 2024-01-03 10:48:30.763851

"""
from typing import Sequence, Union

import sqlalchemy as sa
from alembic import op
from sqlalchemy.dialects import postgresql

# revision identifiers, used by Alembic.
revision: str = "9e1519a34b14"
down_revision: Union[str, None] = None
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.execute(f"CREATE SCHEMA IF NOT EXISTS enum ; ")

    sa.Enum("On", "Off", name="recstatus", schema="enum").create(op.get_bind())
    op.create_table(
        "basic",
        sa.Column(
            "id",
            sa.INTEGER(),
            server_default=sa.text("nextval('enum.basic_id_seq'::regclass)"),
            autoincrement=True,
            nullable=False,
        ),
        sa.Column("name", sa.VARCHAR(), autoincrement=False, nullable=True),
        sa.Column(
            "status",
            postgresql.ENUM("On", "Off", name="recstatus", schema="enum", create_type=False),
            server_default=sa.text("'Off'::enum.recstatus"),
            autoincrement=False,
            nullable=True,
        ),
        sa.PrimaryKeyConstraint("id", name="basic_pkey"),
        schema="enum",
    )

    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.drop_table("basic", schema="enum")
    sa.Enum("On", "Off", name="recstatus", schema="enum").drop(op.get_bind())
    # ### end Alembic commands ###
"""update status

Revision ID: d08530d694c3
Revises: 9e1519a34b14
Create Date: 2024-01-03 11:07:01.326583

"""
from typing import Sequence, Union

from alembic import op
import sqlalchemy as sa
from alembic_postgresql_enum import TableReference

# revision identifiers, used by Alembic.
revision: str = 'd08530d694c3'
down_revision: Union[str, None] = '9e1519a34b14'
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('enum', 'recstatus', ['On', 'Off', 'Unknown'],
                        [TableReference('basic', 'status', existing_server_default="'Off'::enum.recstatus")],
                        enum_values_to_rename=[])
    # ### end Alembic commands ###


def downgrade() -> None:
    # ### commands auto generated by Alembic - please adjust! ###
    op.sync_enum_values('enum', 'recstatus', ['On', 'Off'],
                        [TableReference('basic', 'status', existing_server_default="'Off'::enum.recstatus")],
                        enum_values_to_rename=[])
    # ### end Alembic commands ###

The error I am seeing on attempting to run alembic upgrade head is the following:

sqlalchemy.exc.ProgrammingError: (psycopg2.errors.UndefinedObject) type "recstatus" does not exist

[SQL: ALTER TABLE enum.basic ALTER COLUMN status SET DEFAULT 'Off'::recstatus]
(Background on this error at: https://sqlalche.me/e/20/f405)

So it looks like somewhere in the building of the query it is forgetting to add the schema to the DEFAULT in the alter table execution.

Some looking through the source code makes me think it has something to do with the rename_default_if_required function but I am unsure.