Добавить / удалить значение типа PostgreSQL ENUM в alembic - PullRequest
0 голосов
/ 12 ноября 2018

У меня проблема с изменением существующего столбца postgresql.ENUM с помощью SQLAlchemy и Alembic.

Я хочу добавить / удалить значение для столбца типа postgresql.ENUM в alembic.

В частности, текущий тип перечисления создается следующими двумя алембическими ревизиями:

# revision 1
def upgrade():
    op.create_table('kernels',
        sa.Column('status', sa.String(), nullable=True),
        ...
    )


# revision 2
kernelstatus_choices = (
    'PREPARING', 'BUILDING', 'RUNNING',
    'RESTARTING', 'RESIZING', 'SUSPENDED',
    'TERMINATING', 'TERMINATED', 'ERROR',
)
kernelstatus = postgresql.ENUM(
    *kernelstatus_choices,
    name='kernelstatus')

def upgrade():
    op.alter_column('kernels', column_name='status', 
                    type_=sa.Enum(*kernelstatus_choices, name='kernelstatus'),
                    postgresql_using='status::kernelstatus')

Теперь я хочу добавить 'PENDING' статус к типу kernelstatus. Поэтому я реализовал, как показано ниже, ссылаясь на некоторые статьи .

prev_kernelstatus_choices = (
    'PREPARING', 'BUILDING', 'RUNNING',
    'RESTARTING', 'RESIZING', 'SUSPENDED',
    'TERMINATING', 'TERMINATED', 'ERROR',
)

prev_kernelstatus = postgresql.ENUM(
    *prev_kernelstatus_choices,
    name='kernelstatus')

curr_kernelstatus_choices = ('PENDING',) + prev_kernelstatus_choices

curr_kernelstatus = postgresql.ENUM(
    *curr_kernelstatus_choices,
    name='kernelstatus')

def upgrade():
    op.execute('ALTER TYPE kernelstatus RENAME TO kernelstatus_old;')
    curr_kernelstatus.create(op.get_bind())
    op.alter_column('kernels', column_name='status', 
                    type_=sa.Enum(*curr_kernelstatus_choices, name='kernelstatus'),
                    postgresql_using='status::text::kernelstatus')
    op.execute('DROP TYPE kernelstatus_old;')

Но он продолжает генерировать следующую ошибку:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) operator does not exist: kernelstatus <> kernelstatus_old
HINT:  No operator matches the given name and argument type(s). You might need to add explicit type casts.
[SQL: 'ALTER TABLE kernels ALTER COLUMN status TYPE kernelstatus USING status::text::kernelstatus']

Я уже пробовал решение с добавлением значения к типу перечисления , но это не работает с Alembic, поскольку каждая ревизия Alembic выполняется в транзакции, а оператор ALTER TYPE не может выполняться в транзакции. Кроме того, должен быть код для downgrade(), и в PostgreSQL нет оператора для удаления значения из типа enum, поэтому простое добавление значения в тип enum не может быть окончательным решением в моем случае.

Может ли кто-нибудь помочь мне?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...