2014-01-10 78 views
2

在schemamigration中是不是可以像South一樣做下面的事情?Django 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遷移是因爲這很重...

我知道這不是「做的方式」,但在我看來,這將是老實說,更乾淨。

會有一個真正的問題,這樣做順便說一句嗎?

+0

我會嘗試在模型字典中包含「添加」模型。然後像''create_table'一樣可以像往常一樣簡單地使用'self.orm.Added',但我沒有測試它。 – esauro

回答

1

我想你的目標是確保刪除不會在數據遷移之前運行。爲此,您可以使用dependency system in South

可以打破上述分爲三個部分:

001_app1_addition_migration(在應用程序1)

然後

001_app2_data_migration(在應用程序2,其中富模型屬於)

,然後

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

好的。但是我希望做的只是寫一次遷移,讓我的想法變得更加清晰...... – lajarre

0

首先,南方提供的orm是您正在遷移到的那個orm。換句話說,它在遷移完成後與模式匹配。所以你可以寫orm.Added而不是self.prev_orm.Added。這個事實的另一個含義是你不能參考foo.bar,因爲它不存在於最終模式中。

解決這個問題(並回答你的問題)的方法是跳過ORM,只是execute raw SQL directly

在你的情況下,創建一個訪問已刪除的行會看起來像聲明:

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) 
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 

所以......同時不建議混合架構和數據遷移它,一旦你commitdb.commit_transaction()的架構表格應該可供您使用。請注意提供一個backwards()方法,它可以正確反向地執行步驟。