Question

I want to change my Model

class Source(models.Model):
    release_date = models.DateField()

to

class Source(models.Model):
    release_date = models.IntegerField()

as expected, I get an error

django.db.utils.DataError: (1264, "Out of range value for column 'release_date' at row 1")

What I actually want is, to only save the year in the IntegerField as that is all I need. Is there a very intelligent way to take existing dates' year field and migrate it to the new IntegerField by altering the method

def forwards(self, orm):

If not, how at all can I change the fieldtype without loosing all data, loosing the stored dates, would be a price i'd pay.

Was it helpful?

Solution

One option is to split the task into 3 migrations:

  • schema migration: adding release_year field
  • data migration: filling release_year field from release_date field
  • schema migration: remove release_date field and rename release_year to release_date

Schema migrations would be caught by south automagically (using schemamigration --auto), but you need to write a data migration manually, here's how your forwards() method should look like:

def forwards(self, orm):
    for source in orm.Source.objects.all():
        source.release_year = source.release_date.year
        source.save()

Hope that helps.

OTHER TIPS

Alecxe's answer really helped me, this is how I implemented this in Django 2.2 as of May 2019:

0042_migration.py

# Generated by Django 2.2 on 2019-05-03 20:35

from django.db import migrations

def forwards(apps, schema_editor):
    if schema_editor.connection.alias != 'default':
        return
    MyModel = apps.get_model('my_app', 'MyModel')
    for object in MyModel.objects.all():
        object.new_column = object.old_column
        object.save()

class Migration(migrations.Migration):

    dependencies = [
        ('my_app', '0041_previous_migration'),
    ]

    operations = [
        migrations.RunPython(forwards),
    ]
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top