Data Seeding/Migration in Django

putu agastya
Software Project Course Blog - Marjinal
4 min readMay 14, 2020

Migration

Schema migration adalah proses yang dilakukan ketika terjadi sebuha perubahan pada database schema, seperti penambahan table baru atau penambahan column baru pada existing table. Dalam framework Django migration ditangani oleh 2 perintah yaitu makemigrations dan migrate.

Perintah makemigrations akan akan membuat migration file berdasarkan perubahan yang terjadi pada models yang kita definisikan. Dan perintah migrate akan menerapkan perubahan paada models ke database.

Data migration pada development Digipus

Terkadang saat 2 orang mengerjakan 1 app yang sama dan kedua nya melakukan perubahan terhadap models masing-masing perubahan dapat tercatat pada miggration file dengan nomor yang sama, apa bila ini terjadi django akan mendeteksi migration conflict saat menjalankan perintah migrate. Solusi dari masalah ini adalah menjalankan perintah makemigrations dengan flag -merge.

python manage.py makemigrations –merge

Perintah tersebut akan membuat file migration baru dengan kedua perubahan yang ada pada file migration yang mengalami conflict.

Catatan: Dalam pengembangan digipus sering terjadi masalah migration yang berakhir dengan menghapus semua file migration dan menjalankan makemigration lagi untuk mengenerate migration file yang baru. Sebenar django memiliki fitur squash migration untuk “menyimpulkan” semua file migration yang ada menjadi 1 file migration.

Satu lagi catatan unik, dalam pengembangan salah satu app terus menerus mengeluarkan file migration baru setiap kali makemigrations dijalankan tanpa mengubah models. Ternyata hal ini terjadi karena salah satu developer memasukan sebuah fungsi sebagai defaul dari sebuah field, namun dengan cara yang salah.

def generate_random_color_code():
color = "%06x" % random.randint(0, 0xFFFFFF)
return color
# Contoh 1
class Comment(models.Model):
...
profile = models.CharField(max_length=100, default=generate_random_color_code) #Benar
...
# Contoh 2
class Comment(models.Model):
...
profile = models.CharField(max_length=100, default=generate_random_color_code()) #Salah
...

Pada contoh 2 setiap kali kita menjalankan makemigration fungsi generate_random_color_code akan dijalankan dan menghasilkan default string baru, maka akan mengenerate migration file dimana operasi yang dilakukan adalah mengganti default value dari field tersebut. Cara yang benar adalah contoh 1 dimana kita mempasing fungsi nya dan bukan hasil evaluasi dari fungsi tersbut.

Data Seeding

Data seeding merupakan proses memasukan data awal ke database. Data awal yang dimasukan bisa berupa dummy data atau data penting seperti kredential akun admin. Data seeding sangat berguna untuk kepentingan development, demo ataupun flow dari aplikasi itu sendiri.

Data seeding pada development Digipus

Pada masa pengembangan aplikasi dimana database dapat berubah dan belum ada data penting, seringkali kita mendrop table karena conflik pada saat migration. Untuk itu diperlukan sebuah cara untuk kembali memasukan data penting ke database seperti kredensial Kontributor dan Admin. Selain data kredensial, untuk seorang kontributor dapat menggungah file diperlukan juga data Kategori materi. Maka data seeding dapat menjadi solusi dari masalah tersebut.

Django memiliki fitur fixtures untuk melakukan dataseeding. Namun sebelum melakukan dataseeding kita perlu terlebih dahulu mendefinisikan data yang akan kita masukan ke databse. Kita dapat menggunakan data yang sudah ada di dalam database sebagai input untuk proses data seeding. Untuk menggunakan data yang sudah ada di database, kita bisa menggunakan perintah dumpdata ang dijalankan dari manage.py.

py manage.py dumpdata --indent 2

Hasil dari perintah tersebut adalah data yang ada di database dengan format JSON

{
"model": "app.category",
"pk": 1,
"fields": {
"name": "kategori A",
"description": "Sebuah kategori A"
}
},
{
"model": "app.category",
"pk": 2,
"fields": {
"name": "kategori B",
"description": "Sebuah kategori B"
}
},
...
{
"model": "authentication.user",
"pk": 1,
"fields": {
"password": "pbkdf2_sha256$180000$LNXsQvMhF33i$S/6QxFwpEKG7HzysqMIVCUL/EDHeT+vzbLWbkaKDdCI=",
"last_login": null,
"is_superuser": false,
"first_name": "",
"last_name": "",
"is_staff": false,
"is_active": true,
"date_joined": "2020-04-06T19:07:20.546Z",
"email": "admin@gov.id",
"username": "",
"name": "Admin",
"is_admin": true,
"is_contributor": false,
"instansi": "",
"nik": "",
"alamat": "",
"nomor_telpon": "",
"linkedin": "",
"facebook": "",
"twitter": "",
"instagram": "",
"biography": "Loren ipsum",
"profile_picture": "default-image.png",
"groups": [],
"user_permissions": []
}
},
{
"model": "authentication.user",
"pk": 2,
"fields": {
"password": "pbkdf2_sha256$180000$rbJ4Ui6aUbbk$lX+WdeZhGHBCvd2wbfY/t9synOobgwQmrWtGphbA18Q=",
"last_login": null,
"is_superuser": false,
"first_name": "",
"last_name": "",
"is_staff": false,
"is_active": true,
"date_joined": "2020-04-06T19:07:20.546Z",
"email": "kontributor@gov.id",
"username": "",
"name": "Kontributor",
"is_admin": false,
"is_contributor": true,
"instansi": "",
"nik": "",
"alamat": "",
"nomor_telpon": "",
"linkedin": "",
"facebook": "",
"twitter": "",
"instagram": "",
"biography": "Loren ipsum",
"profile_picture": "default-image.png",
"groups": [],
"user_permissions": []
}
},

kemudian output dari dumpdata dimasukan ke dalam file <nama_app>/fixtures/<nama_fixtures>.json . Pada proses seeding, django akan mencari folder /fixtures/ yang ada di dalam app untuk data seeding dan nama_fixtures yang kita berikan akan digunakan dalam perintah loaddata yang digunakan untuk menjalankan data seeding.

Contoh data untuk seeding.

Setelah kita memiliki fixtures kita dapat melakukan dataseeding setelah melakukan migrate pada database baru.

py manage.py loaddata initial

Catatan: dalam proyek digipus kita hanya mendefinisikan 1 data seed ya itu initial.json yang berisikan kredensial akun dan kategori materi. kedepan nya mungkin kita dapat menambahkan data seed materi, namun perlu diketahui juga bahwa ada perbedaan antara data seeding dan fitur export import.

--

--