Python 从一对一到一到多移动时如何执行数据迁移

Python 从一对一到一到多移动时如何执行数据迁移,python,django,django-models,django-south,Python,Django,Django Models,Django South,我正在使用south来管理迁移,我遇到了困难。基本上,我有以下设置: App1: class A(models.Model): # bunch of attributes class B(models.Models): instance_a = models.OneToOneField(A, null=True, blank=True, editable=False) class A(models.Model)

我正在使用
south
来管理迁移,我遇到了困难。基本上,我有以下设置:

App1

class A(models.Model):
  # bunch of attributes
class B(models.Models):
  instance_a = models.OneToOneField(A, null=True, blank=True, 
                                    editable=False)
class A(models.Model):
  instance_b = models.ForeignKey(B, null=True, blank=True)
class B(models.Models):
  # other attributes
App2

class A(models.Model):
  # bunch of attributes
class B(models.Models):
  instance_a = models.OneToOneField(A, null=True, blank=True, 
                                    editable=False)
class A(models.Model):
  instance_b = models.ForeignKey(B, null=True, blank=True)
class B(models.Models):
  # other attributes
现在,我想从这个到这个:

App1

class A(models.Model):
  # bunch of attributes
class B(models.Models):
  instance_a = models.OneToOneField(A, null=True, blank=True, 
                                    editable=False)
class A(models.Model):
  instance_b = models.ForeignKey(B, null=True, blank=True)
class B(models.Models):
  # other attributes
App2

class A(models.Model):
  # bunch of attributes
class B(models.Models):
  instance_a = models.OneToOneField(A, null=True, blank=True, 
                                    editable=False)
class A(models.Model):
  instance_b = models.ForeignKey(B, null=True, blank=True)
class B(models.Models):
  # other attributes
我的主要问题是我不能丢失数据。因此,基本上在迁移结束时,之前映射到对象B的所有对象A都应该保持该映射。例如,如果id为7的对象A映射到id为8的对象B,则在本过程结束时,应保留此映射

我尝试了几种方法,包括模式迁移、临时占位符迁移和数据迁移。然而,我总是在同一个地方结束,也就是说,在执行数据迁移时,我不再具有以前的关系,以便访问正确的属性。例如,B.instance_a不再可用

我想听听你对两件事的看法:

  • 首先,仅仅使用南迁是否可行
  • 第二,我应如何进行

谢谢

终于过了一段时间,我得到了django south的程序,这可能会帮助其他人。关键是南方的依赖功能(http://south.aeracode.org/wiki/Dependencies). 我分4步完成:

首先

class A(models.Model):
  # bunch of attributes
class B(models.Models):
  instance_a = models.OneToOneField(A, null=True, blank=True, 
                                    editable=False)
class A(models.Model):
  instance_b = models.ForeignKey(B, null=True, blank=True)
class B(models.Models):
  # other attributes
  • 为型号
    a
    中的外键值创建占位符
因此模型
A
变成:

class A(models.Model):
    instance_b_placeholder = models.ForeignKey(A, null=True, blank=True)
class B(models.Model):
     # etc...
现在只需运行
manage.py模式迁移app1--auto

  • 创建数据迁移,以便我们可以复制值。目标是在数据库中复制数据,然后重命名属性并删除旧属性。问题
    manage.py数据迁移app1更新\u字段
    。我选择将数据迁移保留在
    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()
第三

class A(models.Model):
  # bunch of attributes
class B(models.Models):
  instance_a = models.OneToOneField(A, null=True, blank=True, 
                                    editable=False)
class A(models.Model):
  instance_b = models.ForeignKey(B, null=True, blank=True)
class B(models.Models):
  # other attributes
  • 从model
    b
    中删除字段
    instance_b
    ,并确保在上一步中创建的迁移之后运行迁移
型号
B
变为:

class A(models.Model):
    instance_b_placeholder = models.ForeignKey(A, null=True, blank=True)
class B(models.Model):
     # etc...
发布
manage.py schemamigration app2--auto
并编辑迁移将上一次迁移添加到
取决于

depends_on = (
    ("app1", "<migration_number>_update_fields"),
)
就这样。我不知道是否还有那么多其他的方法,但至少这对我有帮助