31

I want my application to have default data such as user types.

What's the most efficient way to manage default data after migrations?

It needs to handle situations such as, after I add a new table, it adds the default data for it.

ivanleoncz
  • 9,070
  • 7
  • 57
  • 49
Dhanushka Amarakoon
  • 3,502
  • 5
  • 31
  • 43

4 Answers4

62

You need to create an empty migration file and Do your stuff in operations block, as explained in docs.

Data Migrations

As well as changing the database schema, you can also use migrations to change the data in the database itself, in conjunction with the schema if you want.

Now, all you need to do is create a new function and have RunPython use it

Docs explains this with an example to show ,how to communicate with your models.

From Docs

To create an empty migration file,

python manage.py makemigrations --empty yourappname

And this is the example how to update a newly added field.

# -*- coding: utf-8 -*-
from __future__ import unicode_literals

from django.db import migrations, models

def combine_names(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 person in Person.objects.all():
        person.name = "%s %s" % (person.first_name, person.last_name)
        person.save()

class Migration(migrations.Migration):
    initial = True

    dependencies = [
        ('yourappname', '0001_initial'),
    ]

    operations = [
        migrations.RunPython(combine_names),
    ]
Community
  • 1
  • 1
durdenk
  • 1,590
  • 1
  • 14
  • 36
  • worked great, but seems like needed to load the whole `Person` table into the memory... isn't there a better way to iterate over all the `Person` objects? – gevra Aug 03 '18 at 13:53
  • Django's way is to use iterators, Person.objects.all().iterator() ? Haven't tested. – durdenk Oct 01 '18 at 19:47
  • Can this be done in the same migration as 0001, _after_ the table gets created? e.g. `operations = [migrations.CreateModel(...), migrations.RunPython(...)]` – Andrew Dec 11 '19 at 03:40
  • Yes, operations is a list and you can modify django-created migration files and add your own functionality. – durdenk Dec 13 '19 at 20:34
  • @durdenk how do you commit this file? Django generally ignores the migration generated files so asking. Do you mention the file in .gitignore to ignore for ignoring? – Bhaskar Dabhi Jul 08 '22 at 05:38
  • @BhaskarDabhi , django has nothing to do with git. Make sure not to include these files in your gitignore and commit migration files. Migration files are a part of your application. – durdenk Jul 18 '22 at 20:55
31

The accepted answer is fine. But, since OP asked the question in the context of adding new rows and not updating existing entries. Here is the code snippet for adding new entries :

from django.db import migrations


class Migration(migrations.Migration):

    dependencies = [
        ('loginmodule', '0002_login_avatar'),
    ]

    def insertData(apps, schema_editor):
     Login = apps.get_model('loginmodule', 'Login')
     user = Login(name = "admin", login_id = "admin", password = "password", email = "admin@pychat.com", type = "Admin", avatar="admin.jpg")
     user.save()


    operations = [
        migrations.RunPython(insertData),
    ]
Binita Bharati
  • 5,239
  • 1
  • 43
  • 24
14

Update:

most users are looking for data migration as suggested by @durdenk in https://stackoverflow.com/a/39742847/3627387. But what OP was asking is about a way to add data after migrations, that is why this is accepted answer.

Original answer:

I think what you are looking for is fixtures https://docs.djangoproject.com/en/1.10/howto/initial-data/

From docs

It’s sometimes useful to pre-populate your database with hard-coded data when you’re first setting up an app. You can provide initial data via fixtures.

Also read this https://code.djangoproject.com/wiki/Fixtures

Sardorbek Imomaliev
  • 14,861
  • 2
  • 51
  • 63
  • 2
    The docs contradict this answer: "If you want to automatically load initial data for an app, don’t use fixtures. Instead, create a migration for your application with RunPython or RunSQL operations." – Dennis Jan 02 '18 at 15:14
  • @Dennis OP asked for "Whats the most efficient way to manage default data after migrations." And even though there was answer about migrations he selected my answer as correct one for his question. – Sardorbek Imomaliev Jan 02 '18 at 15:53
  • @Dennis also the quote you've used from docs is about app not about project. – Sardorbek Imomaliev Jan 03 '18 at 10:07
  • 3
    The whole idea of fixtures, to my understanding, is to prepare sample data mainly for tests. That has nothing to do with defining some permanent default/system/special records for a new table, like OP asked. – drakorg Mar 31 '18 at 19:21
-5

Answer is given above just to show how to insert new rows to the table.

from django.db import migrations, models
from yourapp.models import <yourmodel>

def combine_names(apps, schema_editor):
    obj = <yourmodel>(arrib=value)
    obj.save()

For example let's say you have model Person

person = Person(first_name='raj', last_name='shah')
person.save()
Rajender Saini
  • 594
  • 2
  • 9
  • 24