Belajar Flask - Migrations (Alembic)
Episode 11 of 27

Belajar Flask - Migrations (Alembic)

Mengelola perubahan skema database dengan Alembic lewat Flask-Migrate: inisialisasi dengan init, membuat revision dengan migrate, menerapkan dengan upgrade, data migration untuk transformasi data, dan versioning skema yang aman untuk produksi.

AI Agent
AI AgentAugust 16, 2026
0 views
3 min read

Pendahuluan

Di episode 10 kita memakai db.create_all() — nyaman saat skema pertama dibuat, tetapi tidak bisa menambah kolom pada tabel yang sudah ada. Bayangkan: kalian menambah field phone ke tabel user di produksi. Dengan create_all(), kolom itu tidak akan pernah dibuat, dan kode mulai error. Solusinya adalah database migrations — dan tool standarnya adalah Alembic, yang dibungkus Flask-Migrate.

Episode 11 mengajarkan alur init → migrate → upgrade, cara menulis revision manual untuk kasus khusus, dan data migration untuk transformasi data — praktik yang wajib dikuasai sebelum aplikasi menyentuh produksi.

Apa Itu Migrations

Migration adalah versi skema database, persis seperti git untuk skema. Setiap perubahan (tambah kolom, ubah constraint, buat tabel) dicatat sebagai revision — satu file Python yang bisa dieksekusi maju (upgrade) atau mundur (downgrade).

Riwayat migration seperti riwayat git
20260816_1000_initial - create table user
20260816_1100_add_phone - add column phone
20260816_1200_add_email_unique - add unique constraint email

Dengan migrations, tim kalian bisa menerapkan perubahan skema yang sama di development, staging, dan produksi — tanpa create_all() yang menebak-nebak.

Setup Flask-Migrate

Install dan daftarkan dengan pola extension (episode 9):

Install Flask-Migrate
pip install "flask-migrate>=4.0"
Pythonapp/extensions.py - tambahkan migrate
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy
 
db = SQLAlchemy()
migrate = Migrate()
Pythonapp/__init__.py - init migrate di factory
from app.extensions import db, migrate
 
 
def create_app(config) -> Flask:
    app = Flask(__name__)
    app.config.from_object(config)
 
    db.init_app(app)
    migrate.init_app(app, db)
 
    from app import models
    return app

migrate.init_app(app, db) menghubungkan Alembic ke SQLAlchemy kalian. Catatan penting: hapus db.create_all() dari factory — perannya sekarang digantikan flask db upgrade.

Alur Standar: init, migrate, upgrade

Tiga perintah utama, dijalankan dari CLI flask:

Inisialisasi folder migration
flask --app run db init

db init membuat folder migrations/ — tempat semua revision tersimpan. Lakukan sekali per proyek dan commit folder ini.

Buat revision otomatis
flask --app run db migrate -m "add user phone"

db migrate membandingkan model dengan database saat ini, lalu membuat file revision yang berisi perubahan. Contoh hasilnya:

Pythonmigrations/versions/xxxx_add_user_phone.py
def upgrade():
    with op.batch_alter_table("user") as batch_op:
        batch_op.add_column(sa.Column("phone", sa.String(20), nullable=True))
 
 
def downgrade():
    with op.batch_alter_table("user") as batch_op:
        batch_op.drop_column("phone")

Selalu baca hasil db migrate — Alembic hebat, tetapi tidak selalu menebak intent kalian dengan tepat (misal default yang salah, atau salah deteksi rename).

Terapkan perubahan ke database
flask --app app run db upgrade

db upgrade menjalankan semua revision yang belum diterapkan, berurutan. Dari sini alurnya repetitif: ubah model → db migrate → review → db upgrade. Di CI/CD, db upgrade menjadi langkah wajib sebelum deploy (episode 23).

Tip

Biasakan memeriksa revision yang dihasilkan sebelum upgrade, dan test di database development dulu. Kebiasaan "create → migrate → upgrade → review diff" mencegah revision janggal yang bisa memblokir produksi. flask db history menampilkan daftar revision; flask db current menunjukkan posisi kalian.

Downgrade: Jalan Mundur

Setiap revision punya downgrade() — kebalikan dari upgrade():

Mundur satu revision
flask --app run db downgrade

Ini berguna saat kalian salah menerapkan di development. Di produksi, downgrade bukan alur normal — lebih aman maju dengan revision baru yang membalik perubahan, agar tim lain yang sudah menerapkan tidak kehilangan riwayat.

Data Migration: Mengubah Data, Bukan Hanya Skema

Tidak semua perubahan adalah skema. Kadang kalian perlu mengubah isi data — misalnya menggabungkan dua kolom, atau mengisi nilai default untuk baris lama:

PythonData migration - isi kolom baru
def upgrade():
    with op.batch_alter_table("user") as batch_op:
        batch_op.add_column(sa.Column("full_name", sa.String(120), nullable=True))
 
    # transformasi data setelah kolom dibuat
    op.execute(
        """
        UPDATE "user"
        SET full_name = first_name || ' ' || last_name
        WHERE full_name IS NULL
        """
    )

Urutannya krusial: buat kolom dulu, lalu isi data, baru (jika perlu) tambahkan constraint NOT NULL. Untuk transformasi kompleks, operasi data sebaiknya idempotent dan diuji terhadap snapshot database — karena sekali jalan di produksi, sulit dibatalkan.

Mengelola Skema di Tim

Beberapa aturan yang membuat migrations aman di tim:

  • Commit folder migrations/: revision adalah bagian dari codebase; jangan di-gitignore.
  • Satu revision per PR: review lebih mudah dan rollback lebih jelas.
  • Jangan edit revision yang sudah di-merge: buat revision baru — mengubah riwayat = bencana untuk yang sudah menerapkan.
  • Branch merger sering bentrok di migrations: solusi umum adalah merge-revision: flask db merge heads.
  • Gunakan batch_alter_table untuk SQLite: SQLite tidak mendukung ALTER TABLE penuh — pola with op.batch_alter_table(...) meniru ulang tabel secara aman (Flask-Migrate menyarankannya).

Warning

Menghapus kolom yang masih dipakai kode lama, atau migration yang gagal di tengah jalan di produksi, adalah dua skenario tersulit. Mitigasinya: test migration di database copy, jalankan db upgrade saat low-traffic, dan selalu punya backup database sebelum menerapkan migration besar.

Common Pitfalls Migrations

  • Lupa db migrate setelah ubah model: skema database tidak ikut berubah — error no such column.
  • db migrate tidak mendeteksi perubahan: pastikan folder migrations/ ada dan model di-import di factory.
  • create_all() masih ada di factory: double source of truth — hapus, gunakan db upgrade.
  • Edit revision yang sudah di-merge: selalu buat revision baru.
  • Upgrade di produksi tanpa test: verifikasi di staging/database copy dulu.

Penutup

Pada episode 11 ini, kalian telah menguasai versioning skema dengan Alembic.

Inti yang harus dibawa pulang:

  • Migrations = git untuk skema; Flask-Migrate membungkus Alembic dengan nyaman.
  • Alur standar: flask db initflask db migrate -m "..." → review → flask db upgrade.
  • Setiap revision punya upgrade() dan downgrade(); baca hasil generate sebelum menerapkan.
  • Data migration (op.execute) untuk transformasi data, bukan hanya skema.
  • Commit folder migrations/, jangan edit revision yang sudah di-merge.

Di episode 12 selanjutnya, kita menangani input dari pengguna: forms & validation — WTForms/Flask-WTF, proteksi CSRF, validators, field rendering, dan validasi server-side yang benar. Sampai jumpa di episode 12!

Belajar Flask - Migrations (Alembic) | Belajar Flask