Seeding and Migration in Django: A Story

Satria Bagus
Sulang
Published in
3 min readMar 21, 2018

--

Seeding dan migration bukanlah hal baru dalam sebuah framework yang digunakan dalam mengembangkan web application. Namun sayangnya django tidak menyediakan seeding database secara default. Namun ada beberapa cara untuk mengakalinya.

Pada PPL kali saya menggunakan migration yang sudah disediakan django dalam melakukan migration. Pertama, jika saya memiliki model anggaplah perusahaan dan pekerjaan seperti kode dibawah ini.

class Perusahaan(models.Model):   name = models.CharField(max_length=300, null=True)   description = models.CharField(max_length=500, null=True)   address = models.CharField(max_length=500, null=True)   contact_person = models.CharField(max_length=200)   lastseen_at = models.DateTimeField(         'Last Seen at', auto_now=True, editable=False         )   created_at = models.DateTimeField(        'Created at', auto_now_add=True, editable=False        )class Job(models.Model):    perusahaan = models.ForeignKey(
Perusahaan,
on_delete=models.CASCADE
)
title = models.CharField(max_length=140) date = models.DateTimeField(auto_now_add=True) description = models.TextField(max_length=500) created_at = models.DateTimeField(auto_now_add=True)

Untuk melakukan migrations saya melakukan

python manage.py makemigrations

Hal ini dilakukan untuk membuat migration file, kemudia saya menjalankan

python manage.py migrate

Hal ini dilakukan agar migrasi yang dilakukan mengubah database.

Seeding

Dalam melakukan seeding ada beberapa cara yang bisa dilakukan. Saya akan memaparkan beberapa cara yang bisa digunakan termasuk cara yang saya gunakan.

  1. Menggunakan library django-seed

Penggunaan django db-seed cukup mudah, yaitu hanya menggunakan command:

python manage.py seed lowongan --number=15

Hal ini melakukan seeding setiap models pada apps lowongan dengan 15 data awal.

2. Menggunakan fixtures pada Django

Penggunaan fixtures juga cukup mudah yaitu hanya membuat sebuah file yaml, json , ataupun xml pada direktori fixtures didalam apps.

lowongan
├── admin.py
├── __init__.py
├── fixtures
│ ├── job.yaml
│ └── __init__.py
├── models.py
... other files

Lalu pada job.yaml tambahkan data yang ingin di seed pada database.

- model: lowongan.perusahaan  pk: 1  fields:    name: PT Palsu    description: Deskrpsi Palsu    address: Jalan palsu    contact_person: +62816272181    created_at: 2018-03-20T10:32:33.448863Z    lastseen_at: 2018-03-20T10:32:33.448863Z- model: lowongan.job  pk: 1  fields:     perusahaan: 1     title: Job Palsu     description: Deskripsi Palsu     created_at: 2018-03-20T10:32:33.448863Z     date: 2018-03-20T10:32:33.448863Z

Lalu jalankan perintah:

python manage.py loaddata job

3. Modifikasi pada file migrations python

Jalankan command

python manage.py makemigrations yourappname --empty

Lalu pada empty migrations data tambahkan

from __future__ import unicode_literals
from django.db import migrations

def stream_from_api():
...

def load_data(apps, schema_editor):
# We can't import the Person model directly as it may be a newer
# version than this migration expects. We use the historical version.
Person = apps.get_model('yourappname', 'Person')

for item in stream_from_api():
person = Person(first=item['first'], last=item['last'], age=item['age'])
person.save()

class Migration(migrations.Migration):
dependencies = [('yourappname', '0009_something')]
operations = [migrations.RunPython(load_data)]

sumber: https://stackoverflow.com/questions/47296560/django-1-10-seed-database-without-using-fixtures

4. Membuat command

Buat file seperti dalam direktori

blogapp
├── admin.py
├── __init__.py
├── management
│ ├── commands
│ │ ├── __init__.py
│ │ └── populate_db.py
│ └── __init__.py
├── models.py
... other files

Lalu tambahkan kode ini pada populate_db.py

from django.core.management.base import BaseCommand
from blogapp.models import Post, Tag

class Command(BaseCommand):
args = '<foo bar ...>'
help = 'our help string comes here'

def _create_tags(self):
tlisp = Tag(name='Lisp')
tlisp.save()

tjava = Tag(name='Java')
tjava.save()

def handle(self, *args, **options):
self._create_tags()

Lalu tinggal jalankan command

python manage.py populate_db

Keempat cara diatas memiliki kelebihan dan kekurangan masing-masing namun secara keseluruhan metode seeding pada django belum ada metode yang nyaman dan sempurna seperti pada ruby ataupun PHP.

--

--