是不是可以在模式移植中使用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会出现真正的问题吗?
答案 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()
方法,以便向后执行正确的步骤。