Saya telah menggunakan pengaturan menggunakan SQLAlchemy dan migrasi Alembic bersama dengan DB Postgres di backend. Saya telah menggunakan enum di beberapa DB-Model sebagai tipe data dan saya telah menggunakan Enum-Type di SQLAlchemy dan (karena ini) juga di dalam Postgres. Sepanjang pengembangan yang berkelanjutan, saya memutuskan untuk mengganti enum tersebut dengan bilangan bulat, untuk beberapa alasan yang lebih kecil (termasuk fleksibilitas yang lebih tinggi saat menambahkan nilai baru, yang akan memerlukan migrasi DB sekarang yang mengubah tipe data dan mengubah yang dalam alembic agak rumit dan enums tampaknya kurang portabel untuk sistem db lain daripada ints). Saya harus membuat migrasi karena ini yang mengubah tipe data kolom enum menjadi int menggunakan migrasi alembic.

Sayangnya saya belum menemukan metode konversi apa pun, yang memungkinkan saya untuk mempertahankan nilai-nilai lama selama migrasi. Saya telah menggunakan IntEnums, yang memetakan nilai enum ke bilangan bulat dengan python, tetapi Postgres tidak menggunakan pemetaan ini secara internal, sehingga tidak memiliki informasi tentang nilai yang seharusnya dari enum saat mengonversinya menjadi bilangan bulat. Dari sudut pandang saya, entah bagaimana saya harus memberikan pemetaan eksplisit nama enum ke integer saat menerapkan kueri tabel ubah. Postgres memberikan pernyataan using , tetapi saya tidak dapat menemukan cara menggunakan ini untuk memetakan nilai dari nilai enum saya ke nilai integer baru/lama yang telah digunakan python.

Jadi bagaimana seharusnya pernyataan penggunaan seperti itu jika harus memetakan nilai lama (berbasis enum) ke nilai baru (berbasis int) jika saya harus secara manual memberikan pemetaan untuk itu?

Contoh enum seperti itu:

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

Kolom (lama di DB):

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

Kolom (baru):

sex = db.Column(db.Integer)

Perintah migrasi sekarang:

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

Null mungkin harus diganti dengan yang lain.

Juga, perlu dicatat bahwa akan sangat bagus jika migrasi akan kompatibel dengan sistem DB lain, yang akan memaksa saya untuk menggunakan sistem lain selain pernyataan using, bukan?

1
Raandom 23 Desember 2017, 18:49

1 menjawab

Jawaban Terbaik

Oke menemukannya. Terima kasih kepada Ilja untuk tip dengan KASUS.

Pada dasarnya diganti 'null' dengan

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

Yang membawa migrasi hidup tanpa harus mengatur semua nilai itu dengan cara lain. Saya tidak berpikir ini sepenuhnya memenuhi persyaratan portabilitas yang saya miliki, hanya karena saya masih menggunakan klausa penggunaan postgres. Selain itu, pernyataan kasus sederhana berfungsi.

0
Raandom 27 Desember 2017, 14:41