Django South - 同时进行架构和数据迁移

时间:2014-01-10 18:37:50

标签: django django-south data-migration schema-migration

是不是可以在模式移植中使用South执行以下操作?

def forwards(self, orm):
    ## CREATION
    # Adding model 'Added'
    db.create_table(u'something_added', (
        (u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
        ('foo', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['something.Foo'])),
        ('bar', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['something.Bar'])),
    ))
    db.send_create_signal(u'something', ['Added'])

    ## DATA
    # Create Added for every Foo
    for f in orm.Foo.objects.all():
        self.prev_orm.Added.objects.create(foo=f, bar=f.bar)

    ## DELETION
    # Deleting field 'Foo.bar'
    db.delete_column(u'something_foo', 'bar_id')  

查看允许我访问prev_orm的{​​{1}},然后执行 all in one 。我发现必须为此编写3次迁移非常重...

我知道这不是“做的方式”,但在我看来,这实际上要更加清洁。

btw会出现真正的问题吗?

3 个答案:

答案 0 :(得分:1)

我想您的目标是确保在数据迁移之前不会执行删除操作。为此,您可以使用dependency system in South

您可以将上述内容分为三个部分:

001_app1_addition_migration(在应用1中)

然后

001_app2_data_migration(在应用2中,Foo模型所属的地方)

然后

002_app1_deletion_migration(在应用1中)包含以下内容:

class Migration:

    depends_on = (
        ("app2", "001_app2_data_migration"),
    )

    def forwards(self):
        ## DELETION
        # Deleting field 'Foo.bar'
        db.delete_column(u'something_foo', 'bar_id')

答案 1 :(得分:0)

首先,南方提供的orm是你要移植到的那个。换句话说,它在迁移完成后与模式匹配。因此,您只需撰写orm.Added而不是self.prev_orm.Added。这个事实的另一个含义是你不能引用foo.bar,因为它不存在于最终的模式中。

解决这个问题(并回答你的问题)的方法是跳过ORM而只是execute raw SQL directly

在您的情况下,访问已删除行的create语句类似于:

cursor.execute('SELECT "id", "bar_id" FROM "something_foo"')
for foo_id, bar_id in cursor.fetchall()
    orm.Added.ojbects.create(foo_id=foo_id, bar_id=bar_id)

答案 2 :(得分:0)

南方迁移正在使用transaction management

一次进行多次迁移时,代码类似于:

for migration in migrations:
    south.db.db.start_transaction()
    try:
        migration.forwards(migration.orm)
        south.db.db.commit_transaction()
    except:
        south.db.db.rollback_transaction()
        raise

所以...虽然不推荐混合架构和数据迁移,但是commit架构db.commit_transaction()表格应该可供您使用。请注意提供backwards()方法,以便向后执行正确的步骤。