class Stop(models.Model):
geo_region = models.CharField(max_length=255, default="")
我需要在此类中将字段类型更改为外键,以保留数据。所以我创建了下面的类并进行了schemamigration和datamigration以将geo_name值保存到新表中。
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
我改变了geo_region的字段类型。
class Stop(models.Model):
geo_region = models.ForeignKey(GeoRegion)
然后我再次运行south schemamigration命令并出错;
DatabaseError: column "geo_region_id" cannot be cast to type integer
如何解决此问题并将现有geo_name值与新外键匹配?
答案 0 :(得分:1)
我通过以下数据迁移解决了这个问题,然后使用schemamigration将charfield转换为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()
答案 1 :(得分:0)
Stop
字段下的geo_region
数据库表中有旧数据。 South正在获取该数据并尝试将其放入新的models.ForeignKey()
字段(期望geo_region模型的实例)。您需要编写一个数据迁移(例如,参见South documentation),它可以删除旧数据或转换它,例如:
def forwards(self, orm):
for stop in orm.Stop.objects.all():
geo_region = GeoRegion.objects.get(geo_name=stop.geo_region)
stop.geo_region = geo_region
stop.save()
未经测试的代码,但应该类似。您可能还想编写backwards()
方法。