南将DateField迁移到IntegerField

时间:2014-03-14 19:12:52

标签: django integer django-south database-migration

我想改变我的模型

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

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

如预期的那样,我收到错误

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

我真正想要的是,只保存IntegerField中的那一年,因为这就是我所需要的。是否有一种非常智能的方法来获取现有日期的年份字段并通过更改方法将其迁移到新的IntegerField

def forwards(self, orm):

如果没有,我怎么能更改字段类型而不丢失所有数据,丢失存储的日期,这将是我付出的代价。

2 个答案:

答案 0 :(得分:3)

一种选择是将任务拆分为3次迁移:

  • 架构迁移:添加release_year字段
  • data migration:填写release_year字段
  • 中的release_date字段
  • 架构迁移:移除release_date字段并将release_year重命名为release_date

模式迁移将由南方自动捕获(使用schemamigration --auto),但您需要手动编写数据迁移,以下是forwards()方法的外观:

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

希望有所帮助。

答案 1 :(得分:1)

Alecxe的回答确实帮助了我,这就是我自2019年5月起在Django 2.2中实现此功能的方式:

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),
    ]