我正在使用南方来管理迁移,我已经到了一个角落.基本上我有以下设置: 应用1: class A(models.Model): # bunch of attributes 应用2: class B(models.Models): instance_a = models.OneToOneField(A, null=True, blank
应用1:
class A(models.Model): # bunch of attributes
应用2:
class B(models.Models): instance_a = models.OneToOneField(A, null=True, blank=True, editable=False)
现在,我想从此到此:
应用1:
class A(models.Model): instance_b = models.ForeignKey(B, null=True, blank=True)
应用2:
class B(models.Models): # other attributes
我的主要问题是我不能丢失数据.因此,基本上在迁移结束时,先前映射到对象B的所有对象A应保持该映射.例如,如果具有id 7的对象A被映射到具有id 8的对象B,则在该过程结束时应该保留该映射.
我尝试了一些与临时占位符和数据迁移混合的模式迁移.但是我最终总是在同一个地方,这是在执行数据迁移时我不再拥有先前的关系以便访问正确的属性.例如,B.instance_a不再可用.
我希望你对两件事有所了解:
>首先,这是否可行只使用南方迁移.
>其次,我该怎么办呢.
谢谢
终于过了一段时间,我得到了一个django-south的程序,可以帮助别人.关键是南方的depends_on功能(http://south.aeracode.org/wiki/Dependencies).我分四步完成:第一:
>为模型A中的外键值创建占位符.
所以模型A变成:
class A(models.Model): instance_b_placeholder = models.ForeignKey(A, null=True, blank=True)
现在运行manage.py schemamigration app1 –auto.
第二
>创建数据迁移,以便我们可以复制值.目标是将数据复制到数据库中,稍后重命名属性并删除旧属性.发出manage.py datamigration app1 update_fields.我选择在app1中保留数据迁移.如果您不这样做,请确保它在上一次迁移后运行.
这是数据移植编码:
# Forwards: for b in orm['app2.B'].objects.filter(instance_b__isnull=False): b.instance_a.instance_b_placeholder = b b.instance_a.save() # Backwards: for r in orm['app1.A'].objects.filter(instance_b_placeholder__isnull=False): r.instance_b_placeholder.instance_a = r r.instance_b_placeholder.save()
第三:
>从模型B中删除字段instance_b,并确保在上一步中创建的迁移之后运行迁移.
模型B变为:
class B(models.Model): # etc...
发出manage.py schemamigration app2 –auto并编辑迁移,将先前的迁移添加到depends_on:
depends_on = ( ("app1", "<migration_number>_update_fields"), )
第四步:
>重命名占位符.这是通过更改代码中的名称和编辑迁移来实现的.编辑是必要的,因为南方倾向于删除并添加新列,但我们只希望它重命名该列.
>此迁移应该在最后一个位置运行,因此我依赖于前一个迁移.
这是代码:
depends_on = ( ("app2", "<previous_migration_here>"), ) # Forwards: db.rename_column('app1_a', 'instance_b_placeholder_id', 'instance_b_id') # Backwards: db.rename_column('app1_a', 'instance_b_id', 'instance_b_placeholder_id')
就是这样了.我不知道是否还有很多其他方法可以做到这一点,但至少这对我有帮助.