[Django]-Django : Migration of polymorphic models back to a single base class

4👍

There is no need to write an Operations class; data migrations can be done simply with a RunPython call, as the docs show.

Within that function you can use perfectly normal model instance methods; since you know the fields you want to move the data for, there is no need to get them via meta lookups.

However you will need to temporarily call the new body field a different name, so it doesn’t conflict with the old fields on the subclasses; you can rename it back at the end and delete the child classes because the value will be in the base class.

def migrate_answers(apps, schema_editor):
    classes = []
    classes_str = ['AnswerText', 'AnswerInteger']
    for class_name in classes_str:
        classes.append(apps.get_model('survey', class_name))
    for class_ in classes:
        for answer in class_.objects.all():
            answer.new_body = answer.body
            answer.save()

operations = [
    migrations.AddField(
        model_name='answerbase',
        name='new_body',
        field=models.TextField(blank=True, null=True),
    ),
    migrations.RunPython(migrate_answers),
    migrations.DeleteModel(name='AnswerInteger',),
    migrations.DeleteModel(name='AnswerText',),
    migrations.RenameField('AnswerBase', 'new_body', 'body'),
    migrations.RenameModel("AnswerBase", "Answer"),
]

1👍

You could create an empty migration for the app you want to do these modifications and use the migrations.RunPython Class to execute custom python functions.

  1. Inside these functions you can have access to your models
  2. The Django ORM that you can do data manipulation.
  3. Pure python, no raw SQL.

Leave a comment