user2194805
user2194805

Reputation: 1369

Django migration from dynamic fields

I've the following Django model:

class Apple(models.Model):
    text = models.TextField()

I've already many records, and I'd like to add a subject field to the model, so it'll look like:

class Apple(models.Model):
    text = models.TextField()
    subject = models.CharField(max_length = 128)

. In this case I run a makemigrations, but since subject can be empty, I need to set a default value either in the model, or in the migration file.

What would be the correct procedure if I'd like to take the subject from the text for the already existing database lines (for instance: text[:64])?

My solution would be to create a migration with a default value, run a management command to update the values, and with a new migration remove the default value for the subject. Is there a better solution? What is it? Can I somehow combine / do this in the migration itself?

Python: 3.4.5 Django: 1.9.2

Upvotes: 1

Views: 932

Answers (2)

Satendra
Satendra

Reputation: 6865

You can do it in migration itself, create a migration file with blank=True, null=True in subject field.

class Apple(models.Model):
    text = models.TextField()
    subject = models.CharField(max_length=128, blank=True, null=True)

Then create another empty migration file.

python manage.py makemigrations --empty yourappname

Paste below code in that file.

from django.db import migrations

def set_subject(apps, schema_editor):

    Apple = apps.get_model('yourappname', 'Apple')
    for a in Apple.objects.all():
        a.subject = a.text
        a.save()

class Migration(migrations.Migration):

    dependencies = [
        ('yourappname', 'name of above migration file'),
    ]

    operations = [
        migrations.RunPython(set_subject),
    ]

Upvotes: 1

Alasdair
Alasdair

Reputation: 308789

For some databases including postgresql, it can be quicker to add a nullable field, therefore I would change your approach to:

  1. schema migration creates the field with null=True (no need to set a default)
  2. data migration populates the field
  3. schema migration removes null=True from field

You can combine the three operations in one migration file. However the Django docs for data migrations recommend that you keep them separate.

Upvotes: 1

Related Questions