Postgres / SQLAlchemy / Alembic将数据类型从枚举更改为int,并使用using映射值

问题描述 投票:1回答:1

我一直在使用SQLAlchemy和Alembic迁移的设置以及后端的Postgres DB。我一直在使用某些DB-Models中的枚举作为数据类型,我一直在使用SQLAlchemy中的Enum-Type,并且(因为这个)也在Postgres中使用。在整个持续开发过程中,我决定用整数替换这些枚举,原因有些较小(包括在添加新值时具有更高的灵活性,这需要现在改变数据类型的DB迁移并改变alembic中的那些是相当复杂的对于其他数据库系统来说,enums似乎不像int那样可移植)。我必须创建一个迁移,因为这会使用alembic迁移将枚举列的数据类型更改为int。

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

那么如果我必须手动为其提供映射,那么如果它应该将旧的(基于枚举的)值映射到新的(基于int的)值,那么这样的using语句将如何?

这种枚举的一个例子:

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

列(DB中的旧):

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

专栏(新):

sex = db.Column(db.Integer)

现在迁移命令:

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

Null可能必须用其他东西替换。

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

python postgresql enums sqlalchemy alembic
1个回答
0
投票

好的找到了。感谢Ilja的CASE提示。

基本上用'null'代替'null'

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

这使得迁移无需以其他方式设置所有这些值。我不认为这完全符合我的可移植性要求,只是因为我仍在使用postgres的using子句。除此之外,简单的案例陈述也有效。

© www.soinside.com 2019 - 2024. All rights reserved.