如何在 Alembic 迁移(Postgres)中使用已存在的 sqlalchemy 枚举?

23

过去的某个时间点,我运行了一个alembic迁移,创建了一个名为users的表格,例如...

def upgrade():
    ...
    op.create_table(
        "users",
        sa.Column("id", sa.Integer(), autoincrement=True, nullable=False),
        ...
        sa.Column("type", sa.Enum("Foo", "Bar", "Baz", name="usertype"), nullable=False),
        ...
    )
    ...

...其中创建了名为usertype的枚举,其值为"Foo"、"Bar"、"Baz"

现在,我想创建另一个表格,它也引用相同的枚举。例如,

def upgrade():
    ...
    op.create_table('foobar',
        sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
        ...
        sa.Column('user_type', sa.Enum(< ???????? >), nullable=False),
        ...
    )

如何引用现有枚举类型的语法?

我在文档中找不到答案:https://docs.sqlalchemy.org/en/13/core/type_basics.html#sqlalchemy.types.Enum

4个回答

32

要使用Postgres实现这一点,需要两个步骤。

  1. 指定create_type=False
  2. 使用sqlalchemy.dialects.postgresql.ENUM(而不是sqlalchemy.Enum

例如:

from sqlalchemy.dialects import postgresql

sa.Column('my_column', postgresql.ENUM(name='my_enum', create_type=False))

枚举的值是否可以通过内省获得,以便在迁移中不需要重复定义? - pdoherty926
2
我没有尝试过,但我认为你可以省略枚举值:postgresql.ENUM(name='my_enum', create_type=False) - Dean
1
看起来你可以,我会更新我的答案。 - Dean

5
你可能需要传递枚举对象而不是其名称作为字符串。
    entity = Column(
        postgresql.ENUM(
            SocialType,
            create_type=False,
            checkfirst=True,
            inherit_schema=True,
        )
    )

checkfirst=Truecreate_type=False不会被alembic检测到,所以你需要手动添加。最后,alembic迁移应该如下所示:

sa.Column('entity', postgresql.ENUM('github', 'twitter', name='socialtype', schema='dashboard', inherit_schema=True, create_type=False, checkfirst=True), nullable=True),

这也是我发现的 - create_type 在 alembic 中被忽略了。 - Alleo

-1

-3

关于如何修复此错误的信息不多,但以下是您需要做的。

在自动生成迁移后,只需在迁移文件中的枚举字段中添加create_type=False即可。

sa.Column('user_type', sa.Enum(< ???????? >, create_type=False), nullable=False),

1
sa.Enum没有那个关键字参数。 - Alex Grönholm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接