Home > Software design >  Populating db with initial data in Django
Populating db with initial data in Django

Time:06-25

I need a way to populate db with initial data(cities) for my refs. So I've tried to do it through migrations(https://docs.djangoproject.com/en/4.0/topics/migrations/#data-migrations)
Not sure it's a best way, since now I've made changes in this file after migration and can't apply it again, neither can't roll it back(since operation ...populate_cities... is not reversible) and apply again.
So the questions are:

  1. is there a way to roll such migration back(may be manually)?
  2. may be there is a better way to populate db with such data

CodePudding user response:

You can fix the "not reversible" part by making the migration reversible. If you used RunPython operation to populate the database, you also need to create code that reverses this operation.

An example from documentation:

from django.db import migrations

def forwards_func(apps, schema_editor):
    # We get the model from the versioned app registry;
    # if we directly import it, it'll be the wrong version
    Country = apps.get_model("myapp", "Country")
    db_alias = schema_editor.connection.alias
    Country.objects.using(db_alias).bulk_create([
        Country(name="USA", code="us"),
        Country(name="France", code="fr"),
    ])

def reverse_func(apps, schema_editor):
    # forwards_func() creates two Country instances,
    # so reverse_func() should delete them.
    Country = apps.get_model("myapp", "Country")
    db_alias = schema_editor.connection.alias
    Country.objects.using(db_alias).filter(name="USA", code="us").delete()
    Country.objects.using(db_alias).filter(name="France", code="fr").delete()

class Migration(migrations.Migration):

    dependencies = []

    operations = [
        migrations.RunPython(forwards_func, reverse_func),
    ]

Basically, you need a reverse function, which in many cases can be simply:

def reverse_func(apps, schema_editor):
    pass
  • Related