簡體   English   中英

Postgres / SQLAlchemy / Alembic將數據類型從枚舉更改為int並使用映射值

[英]Postgres/SQLAlchemy/Alembic change datatype from enum to int and map value with using

我一直在使用SQLAlchemy和Alembic遷移以及后端的Postgres DB進行安裝。 我一直在一些DB模型中使用枚舉作為數據類型,並且我一直在SQLAlchemy中使用Enum-Type,並且(因此)也在Postgres中使用。 在整個持續的開發過程中,出於一些較小的原因(包括添加新值時的更高靈活性),我決定將這些枚舉替換為整數,這需要立即進行DB遷移,從而更改數據類型並更改Alembic中的那些枚舉是非常復雜且無論如何,枚舉似乎對其他數據庫系統的可移植性要比ints的少。 因此,我必須創建一個遷移,這會使用Alembic遷移將枚舉列的數據類型更改為int。

遺憾的是,我還沒有找到任何轉換方法,可以讓我在整個遷移過程中保留舊值。 我一直在使用IntEnums,它在python中將枚舉值映射為整數,但是Postgres不在內部使用此映射,因此在將枚舉值轉換為整數時它沒有關於枚舉值的信息。 從我的角度來看,在應用更改表查詢時,我必須以某種方式提供枚舉名稱到整數的顯式映射。 Postgres提供了using語句,但是我一直無法找出如何使用它來將值從我的枚舉值映射到python一直在使用的新/舊整數值。

那么,如果我必須手動提供一個映射,那么它將如何將舊的(基於枚舉的)值映射到新的(基於int的)值呢?

這樣的枚舉的一個示例:

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')

空值可能必須用其他東西代替。

另外,應該指出的是,如果遷移與其他數據庫系統盡可能兼容,那將是一件很不錯的事情,這將迫使我使用另一個系統,而不是using語句,不是嗎?

好的,找到它了。 感謝Ilja提供的CASE小費。

基本上將“ null”替換為

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

這使遷移得以進行,而不必以其他方式設置所有這些值。 我認為這不能完全滿足我的可移植性要求,僅因為我仍在使用postgres的using子句。 除此之外,簡單的case語句還可以工作。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM