djangodjango-south

Django south migration - column cannot be cast to type integer


class Stop(models.Model):
    geo_region = models.CharField(max_length=255, default="")

I need to change the field type to a foreign key in this class, keeping the data. So I made the below class and did the schemamigration and datamigration to save the geo_name values into the new table.

class GeoRegion(models.Model):
    geo_name = models.CharField(max_length=255, unique=True, verbose_name=u'Name')

    def __unicode__(self):
        return u"%s" % self.name

And I changed the field type of the geo_region.

class Stop(models.Model):
    geo_region = models.ForeignKey(GeoRegion)

Then I run the south schemamigration command again and got an error;

DatabaseError: column "geo_region_id" cannot be cast to type integer

How can I resolve this issue out and match the existing geo_name values to the new foreign key?


Solution

  • I resolved this issue by the below datamigration and then schemamigration to convert the charfield to foreignkey.

    class Migration(DataMigration):
    
    def forwards(self, orm):
        for region in orm['runs.Stop'].objects.distinct('geo_region'):
            orm['runs.GeoRegion'].objects.create(geo_name=region.geo_region)
        db.start_transaction()
        db.add_column('runs_stop', 'geo_region_tmp', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
        db.commit_transaction()
        db.start_transaction()
        db.execute('Update runs_stop AS R SET geo_region_tmp=s.id FROM runs_georegion S WHERE S.geo_name=R.geo_region')
        db.delete_column('runs_stop', 'geo_region')
        db.add_column('runs_stop', 'geo_region', self.gf('django.db.models.fields.IntegerField')(default=0), keep_default=False)
        db.commit_transaction()
        db.start_transaction()
        db.execute('Update runs_stop SET geo_region=geo_region_tmp')
        db.delete_column('runs_stop', 'geo_region_tmp')
        db.commit_transaction()