我可以将架构和数据(南)迁移合并为一个吗?

Ing*_*upp 14 django-south

我想使用South 将字段的鸣喇叭和数据从一个模型移动到另一个模型:

class Foo(models.Model):
    foofield = models.CharField()
    honk = models.PositiveIntegerField()

class Bar(models.Model):
    barfield = models.CharField()
Run Code Online (Sandbox Code Playgroud)

我以前做过这个,使用3次单独的迁移:

  1. 模式迁移,将honk添加到Bar
  2. 数据迁移,将所有Foo.honk数据复制到Bar.honk
  3. 另一个模式迁移,从Foo中删除了honk

我可以在一次迁移中执行这三个步骤吗?

我已经了解到南方的模式和数据迁移之间没有太大差别,所以我想也许这样的东西可能会起作用(这就是上面的三个迁移只是一个):

class Migration(DataMigration):
    def forwards(self, orm):
        # add column
        db.add_column('myapp_bar', 'honk', self.gf('django.db.models.fields.PositiveIntegerField')(default='0'), keep_default=False)

        # copy data
        for foo in Foo.objects.all():
            # find the right bar here and then ...
            bar.honk = foo.honk
            bar.save()

        # remove old column
        db.delete_column('myapp_foo', 'honk')
Run Code Online (Sandbox Code Playgroud)

这会起作用还是会失败,因为我(南方冻结)的orm还不知道Bar.honk呢?或者我做错了,在一次迁移中有更好的方法来做这种事情吗?

Ing*_*upp 15

由于这个问题为我赢得了Tumbleweed徽章,我已经挖了并亲自尝试过.这是我发现的.

不,你不能合并这些迁移

因为ORM冻结仅包含要迁移到的模式.因此在上面的示例中,在数据迁移(for循环)期间无法访问foo.honk,因为它在模式迁移期间被删除,因此它不在冻结的ORM中.此外,如果您尝试访问数据,您将获得DatabaseError异常,因为数据库中的列尚未与模型中的列匹配(即,如果您尝试在db.add_column之前访问任何内容).

看起来没有简单的快捷方式,做这样的事情确实需要上面提到的3次迁移.

  • 我想补充一点,这就是`symmetrical = True`在数据迁移中的用途.假设数据迁移在前后具有一致的模式,因此您可以使用`orm`来访问"前进"和"后退"迁移中的冻结模型.由于架构迁移不是这种情况,因此不应在架构迁移中移动任何数据.另外,*不要*在数据迁移中导入模型名称; 相反,从"orm"的冻结模型中分配这些名称.手册对此并不十分清楚,所以我想我会在这里包含这些信息. (2认同)