Seeding and Migration in Django: A Story
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.
Dalam melakukan seeding ada beberapa cara yang bisa dilakukan. Saya akan memaparkan beberapa cara yang bisa digunakan termasuk cara yang saya gunakan.
- 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.