2014-01-10 7 views
2

스키마 마이 그 레이션에서 다음과 같은 작업을 수행 할 수 있습니까? 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') 

f.bar에 액세스 할 수 있도록 할 것 prev_orm 참조, 한에 모든 작업을 수행 할 수 있습니다. 나는 3 개의 마이 그 레이션을 작성하는 것은 꽤 무거웠다는 것을 알게되었습니다 ...

저는 이것이 "할 수있는 방법"이 아니라는 것을 알고 있지만 제 마음에는 솔직히 훨씬 더 깨끗합니다.

btw를 수행하는 데 실제 문제가 있습니까?

+0

"추가 된"모델을 모델명에 포함 시키려고합니다. 그런 다음 평소와 같이'self.orm.Added'를 사용하여'create_table' 후에 사용할 수 있지만 테스트하지는 않았습니다. – 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

우선, South에서 제공 한 orm이 사용자가 마이그레이션하는 Orm입니다. 즉, 이주가 완료된 후 스키마와 일치합니다. 따라서 self.prev_orm.Added 대신 orm.Added을 쓸 수 있습니다. 이 사실의 또 다른 의미는 foo.bar이 최종 스키마에 존재하지 않으므로 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을 사용하고 있습니다 : 귀하의 경우

은 같을 것입니다 삭제 된 행에 액세스 문을 만들 수 있습니다.

한 번에 여러 마이그레이션을 수행 할 때, 코드가 유사하다 : 스키마 및 데이터 마이그레이션을 혼합을하지 않는 것이 좋습니다 동안 db.commit_transaction()하면 commit 한 번 스키마,

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 

그래서 ... 테이블을 사용할 수 있어야합니다. 올바른 단계를 거친 backwards() 방법을 제공하는 것에 유의하십시오.