【问题标题】:Postgres/SQLAlchemy/Alembic change datatype from enum to int and map value with usingPostgres/SQLAlchemy/Alembic 将数据类型从枚举更改为 int 并使用映射值
【发布时间】:2018-06-05 20:04:23
【问题描述】:

我一直在使用使用 SQLAlchemy 和 Alembic 迁移以及后端中的 Postgres 数据库的设置。我一直在一些 DB 模型中使用枚举作为数据类型,并且我一直在 SQLAlchemy 中使用枚举类型,并且(因此)也在 Postgres 中使用枚举类型。在持续的开发过程中,出于一些较小的原因(包括添加新值时的更高灵活性,这将需要立即进行 DB 迁移以更改数据类型并且更改 alembic 中的那些是相当复杂和无论如何,枚举似乎对其他数据库系统的可移植性不如整数)。我必须创建一个迁移,因为这会使用 alembic 迁移将枚举列的数据类型更改为 int。

遗憾的是,我还没有找到任何转换方法,这可以让我在整个迁移过程中保留旧值。我一直在使用 IntEnums,它将枚举值映射到 python 中的整数,但 Postgres 在内部不使用此映射,因此在将枚举转换为整数时它没有关于枚举的假定值的信息。从我的角度来看,在应用更改表查询时,我必须以某种方式提供枚举名称到整数的显式映射。 Postgres 提供了 using 语句,但我一直无法找到如何使用它来将我的枚举值中的值映射到 python 一直在使用的新/旧整数值。

如果我必须手动提供映射,那么如果它应该将旧的(基于枚举的)值映射到新的(基于整数的)值,那么这样的 using 语句应该是什么样子呢?

这种枚举的一个例子:

class SexEnum(enum.IntEnum):
    male = 0
    female = 1

列(数据库中的旧):

sex = db.Column(db.Enum(SexEnum))

列(新):

sex = db.Column(db.Integer)

立即迁移命令:

op.alter_column('users', 'sex',
           type_=sa.Integer, postgresql_using='null')

Null 可能必须替换为其他内容。

另外,应该注意的是,如果迁移尽可能与其他数据库系统兼容,那就太好了,这将迫使我使用除 using 语句之外的另一个系统,不是吗?

【问题讨论】:

  • CASE 表达式可能会很方便。

标签: python postgresql enums sqlalchemy alembic


【解决方案1】:

好的,找到了。感谢 Ilja 提供有关 CASE 的提示。

基本上将'null'替换为

'(CASE sex WHEN \'male\'... END)'

无需以其他方式设置所有这些值即可实现迁移。我认为这并不能完全满足我的可移植性要求,只是因为我仍在使用 postgres 的 using 子句。除此之外,简单的 case 语句也有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-04-09
    • 2012-08-03
    • 1970-01-01
    • 2018-08-01
    • 2013-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多