使用django迁移更改列类型

时间:2014-12-09 17:30:59

标签: django django-migrations

考虑这个结构:

some_table(id: small int)

我想改变它:

some_table(id: string)

现在我通过三次迁移来实现这一目标:

  1. 使用类型字符串
  2. 创建新列_id
  3. (datamigration)通过字符串转换将数据从id复制到_id
  4. 删除ID并将_id重命名为id
  5. 有没有办法只用一次迁移才能做到这一点?

1 个答案:

答案 0 :(得分:10)

您可以直接将列的类型从int更改为string。请注意,除非启用了严格的sql模式,否则整数将被截断为最大字符串长度并且数据可能会丢失,因此请始终进行备份并选择足够高的max_length。此外,迁移不能轻易逆转(sql不直接支持将字符串列更改为int列),因此备份在此过程中非常重要。

Django pre 1.7 / South

您可以使用db.alter_column。首先,创建一个迁移,但不要应用它,否则你将丢失数据:

>>> python manage.py schemamigration my_app --auto

然后,将forwards方法更改为:

class Migration(SchemaMigration):
    def forwards(self, orm):
        db.alter_column('some_table', 'id', models.CharField(max_length=255))

    def backwards(self, orm):
        raise RuntimeError('Cannot reverse this migration.')

这将更改列以匹配新的CharField字段。现在应用迁移,你就完成了。

Django 1.7 您可以使用AlterField操作更改列。首先,创建一个空迁移:

>>> python manage.py makemigrations --empty my_app

然后,添加以下操作:

class Migration(migrations.Migration):
    operations = [
        migrations.AlterField('some_model', 'id', models.CharField(max_length=255))
    ]

现在运行迁移,Django将更改字段以匹配新的CharField