Altering an Enum field using Alembic

后端 未结 10 1141
故里飘歌
故里飘歌 2020-12-12 21:32

How can I add an element to an Enum field in an alembic migration when using a version of PostgreSQL older than 9.1 (which adds the ALTER TYPE for enums)? This SO question e

10条回答
  •  盖世英雄少女心
    2020-12-12 21:40

    This solution is easy to understand and works really well for both upgrade and downgrade. I've written this answer in more detailed manner.

    Let's say our enum_type looks like this:

    enum_type = ('some_value_1', 'some_value_2')
    

    I want to alter enum_type by adding a new enum, so that it becomes like this:

    enum_type = ('some_value_1', 'some_value_2', 'new_value')
    

    This can be done in this way:

    from alembic import op
    
    
    def upgrade():
        op.execute("COMMIT")
        op.execute("ALTER TYPE enum_type ADD VALUE 'new_value'")
    
    
    def downgrade():
        # Drop 'new_value' from enum_type
        op.execute("ALTER TYPE enum_type RENAME TO enum_type_tmp")
    
        op.execute("CREATE TYPE enum_type AS ENUM('some_value_1', 'some_value_1')")
    
        op.execute("DROP TYPE enum_type_tmp")
    

    NOTE: During downgrade, if you're using enum_type in a table then you can modify the downgrade method as mentioned below:

    def downgrade():
        # Drop 'new_value' from enum_type
        op.execute("UPDATE table_name"
                   " SET column_name_using_enum_type_value = NULL"
                   " WHERE column_name_using_enum_type_value = 'new_value'")    
    
        op.execute("ALTER TYPE enum_type RENAME TO enum_type_tmp")
    
        op.execute("CREATE TYPE enum_type AS ENUM('some_value_1', 'some_value_1')")
    
        op.execute("ALTER TABLE table_name"
                   " ALTER COLUMN column_name_using_enum_type_value TYPE enum_type"
                   " USING column_name_using_enum_type_value::text::enum_type")
    
        op.execute("DROP TYPE enum_type_tmp")
    

提交回复
热议问题