【发布时间】: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