2

在模式迁移中是否可以对 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这将允许我访问f.bar,并做所有在一个。我发现必须为此编写 3 个迁移非常繁重......

我知道这不是“做事的方式”,但在我看来,这真的会更干净。

顺便说一句,这样做会有真正的问题吗?

4

3 回答 3

1

我想您的目标是确保在数据迁移之前不会运行删除。为此,您可以使用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')
于 2014-02-20T17:42:22.940 回答
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()方法来执行正确的倒退步骤。

于 2014-02-26T08:04:17.043 回答
0

首先,South 提供的 orm 是您要迁移到的。换句话说,它在迁移完成后匹配架构。所以你可以只写orm.Added而不是self.prev_orm.Added. 这个事实的另一个含义是您无法引用foo.bar,因为它不存在于最终模式中。

解决这个问题(并回答您的问题)的方法是跳过 ORM 并直接执行原始 SQL

在您的情况下,访问已删除行的 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)
于 2014-02-24T15:14:40.913 回答