Django:使用South将CharField枚举迁移到SmallIntegerField
我有一个模型,其中CharField或多或少充当枚举:Django:使用South将CharField枚举迁移到SmallIntegerField,django,django-south,database-migration,Django,Django South,Database Migration,我有一个模型,其中CharField或多或少充当枚举: grade=models.CharField(max_length='1',choices=('A','B','C')) 不幸的是,由于一些复杂的原因,我不得不将其迁移为一个SmallIntegerField,如下所示: grade=models.SmallIntegerField(选项=(1,2,3)) 在南方我该怎么做?我有一些基本的想法,但不确定如何执行。我的第一个想法是一系列迁移: 添加一个新的grade\u newSmallInt
grade=models.CharField(max_length='1',choices=('A','B','C'))
不幸的是,由于一些复杂的原因,我不得不将其迁移为一个SmallIntegerField,如下所示:
grade=models.SmallIntegerField(选项=(1,2,3))
在南方我该怎么做?我有一些基本的想法,但不确定如何执行。我的第一个想法是一系列迁移:
grade\u new
SmallIntegerField并将旧的等级转换为其中的新等级(在迁移的正向方法期间)grade
字段,同时将grade\u new
重命名为grade
这是正确的方法吗?如果是这样,我将如何在步骤#1中将旧的等级转换为新的等级?虽然我仍然想知道这种方法是否正确,但我能够想出如何通过两次迁移/提交来执行上面的计划 首先,我在模型中添加了一个
new_grade=models.SmallIntegerField(choices=(1,2,3))
字段(这需要复制枚举变量),并在模型的Meta
类的ordering
和unique_一起
字段中,将对grade
的引用更新为new_grade
:
class Foo(models.Model):
A, B, C = 'A', 'B', 'C'
A2, B2, C2, = 1, 2, 3
grade = models.CharField(max_length='1', choices=((A, 'A'), (B, 'B'), (C, 'C')))
new_grade = models.SmallIntegerField(choices=((A2, 1), (B2, 2), (C2, 3)))
class Meta:
ordering = ['x', 'new_grade']
unique_together = ('x', 'new_grade')
运行manage.py schemamigration应用程序--auto
后,我打开了迁移文件,并将转发方法修改为:
def forwards(self, orm):
# For the unique_together...
db.delete_unique('app_foo', ['x', 'grade'])
db.add_column('app_foo', 'new_grade',
self.gf('django.db.models.fields.SmallIntegerField')(default=1),
keep_default=False)
if not db.dry_run:
mapping = {'A': 1, 'B': 2, 'C': 3}
for foo in orm.Foo.objects.all():
foo.new_grade = mapping[foo.grade]
foo.save()
# For the unique_together...
db.create_unique('app_foo', ['x', 'new_grade'])
def forwards(self, orm):
# For the unique_together...
db.delete_unique('app_foo', ['x', 'new_grade'])
db.delete_column('app_foo', 'grade')
db.rename_column('app_foo', 'new_grade', 'grade')
# For the unique_together...
db.create_unique('app_foo', ['x', 'grade'])
运行manage.py migrate app
后,所有的FOO现在都有一个带有映射值的重复的新等级字段。那时我提交了我的代码,因为它处于稳定状态
其次,在models.py中,我删除了旧的grade
字段,重命名了重复的枚举变量,并再次更新了Meta
类中对new_grade
的引用:
class Foo(models.Model):
A, B, C, = 1, 2, 3
grade = models.SmallIntegerField(choices=((A, 1), (B, 2), (C, 3)))
class Meta:
ordering = ['x', 'grade']
unique_together = ('x', 'grade')
我再次运行manage.py schemamigration应用程序--auto
,并打开迁移文件,将转发方法修改为:
def forwards(self, orm):
# For the unique_together...
db.delete_unique('app_foo', ['x', 'grade'])
db.add_column('app_foo', 'new_grade',
self.gf('django.db.models.fields.SmallIntegerField')(default=1),
keep_default=False)
if not db.dry_run:
mapping = {'A': 1, 'B': 2, 'C': 3}
for foo in orm.Foo.objects.all():
foo.new_grade = mapping[foo.grade]
foo.save()
# For the unique_together...
db.create_unique('app_foo', ['x', 'new_grade'])
def forwards(self, orm):
# For the unique_together...
db.delete_unique('app_foo', ['x', 'new_grade'])
db.delete_column('app_foo', 'grade')
db.rename_column('app_foo', 'new_grade', 'grade')
# For the unique_together...
db.create_unique('app_foo', ['x', 'grade'])
运行manage.py migrate app
后,所有的FOO现在都将其grade
字段替换为以前的new_grade
字段,迁移完成