虽然我仍然很想知道这种方法是否正确,但我能够弄清楚如何仅通过两次迁移/提交来执行上述计划。
首先,我向模型添加了一个new_grade = models.SmallIntegerField(choices=(1, 2, 3)) 字段(这需要复制枚举变量),并将模型@987654326 的ordering 和unique_together 字段中对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 app --auto后打开迁移文件,修改forward方法为:
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'])
在运行manage.py migrate app 之后,所有 Foo 现在都有一个重复的带有映射值的 new_grade 字段。那时我提交了我的代码,因为它处于稳定状态。
其次,在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 app --auto,打开迁移文件修改forward方法为:
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 字段,并且迁移完成!