Buraya birkaç kez döndüğümden ve resmileştirmeye karar verdiğimden beri şu anda üzerinde durduğum süreç.
Bu başlangıçta Potr Czachur'un cevabı
ve Matt Briançon'un Güney 0.8.4 kullanarak cevabı üzerine inşa edildi.
Adım 1. Çocuk yabancı anahtar ilişkilerini keşfedin
# Caution: This finds OneToOneField and ForeignKey.
# I don't know if this finds all the ways of specifying ManyToManyField.
# Hopefully Django or South throw errors if you have a situation like that.
>>> Cat._meta.get_all_related_objects()
[<RelatedObject: common:toy related to cat>,
<RelatedObject: identity:microchip related to cat>]
Bu genişletilmiş durumda, aşağıdaki gibi başka bir ilgili model keşfettik:
# Inside the "identity" app...
class Microchip(models.Model):
# In reality we'd probably want a ForeignKey, but to show the OneToOneField
identifies = models.OneToOneField(Cat)
...
2. Adım. Taşıma oluşturun
# Create the "new"-ly renamed model
# Yes I'm changing the model name in my refactoring too.
python manage.py schemamigration specific create_kittycat --auto
# Drop the old model
python manage.py schemamigration common drop_cat --auto
# Update downstream apps, so South thinks their ForeignKey(s) are correct.
# Can skip models like Toy if the app is already covered
python manage.py schemamigration identity update_microchip_fk --auto
Adım 3. Kaynak kontrolü: Şimdiye kadar değişiklikleri gerçekleştirin.
Güncellenen uygulamalarda taşıma işlemleri yazan ekip arkadaşları gibi birleştirme çatışmalarıyla karşılaşırsanız, bunu daha tekrarlanabilir bir süreç haline getirir.
Adım 4. Geçişler arasına bağımlılıklar ekleyin.
Temelde create_kittycat
her şeyin mevcut durumuna bağlıdır ve sonra her şey buna bağlıdır create_kittycat
.
# create_kittycat
class Migration(SchemaMigration):
depends_on = (
# Original model location
('common', 'the_one_before_drop_cat'),
# Foreign keys to models not in original location
('identity', 'the_one_before_update_microchip_fk'),
)
...
# drop_cat
class Migration(SchemaMigration):
depends_on = (
('specific', 'create_kittycat'),
)
...
# update_microchip_fk
class Migration(SchemaMigration):
depends_on = (
('specific', 'create_kittycat'),
)
...
Adım 5. Yapmak istediğimiz tabloyu yeniden adlandırma değişikliği.
# create_kittycat
class Migration(SchemaMigration):
...
# Hopefully for create_kittycat you only need to change the following
# 4 strings to go forward cleanly... backwards will need a bit more work.
old_app = 'common'
old_model = 'cat'
new_app = 'specific'
new_model = 'kittycat'
# You may also wish to update the ContentType.name,
# personally, I don't know what its for and
# haven't seen any side effects from skipping it.
def forwards(self, orm):
db.rename_table(
'%s_%s' % (self.old_app, self.old_model),
'%s_%s' % (self.new_app, self.new_model),
)
if not db.dry_run:
# For permissions, GenericForeignKeys, etc to work properly after migrating.
orm['contenttypes.contenttype'].objects.filter(
app_label=self.old_app,
model=self.old_model,
).update(
app_label=self.new_app,
model=self.new_model,
)
# Going forwards, should be no problem just updating child foreign keys
# with the --auto in the other new South migrations
def backwards(self, orm):
db.rename_table(
'%s_%s' % (self.new_app, self.new_model),
'%s_%s' % (self.old_app, self.old_model),
)
if not db.dry_run:
# For permissions, GenericForeignKeys, etc to work properly after migrating.
orm['contenttypes.contenttype'].objects.filter(
app_label=self.new_app,
model=self.new_model,
).update(
app_label=self.old_app,
model=self.old_model,
)
# Going backwards, you probably should copy the ForeignKey
# db.alter_column() changes from the other new migrations in here
# so they run in the correct order.
#
# Test it! See Step 6 for more details if you need to go backwards.
db.alter_column('common_toy', 'belongs_to_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['common.Cat']))
db.alter_column('identity_microchip', 'identifies_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['common.Cat']))
# drop_cat
class Migration(SchemaMigration):
...
def forwards(self, orm):
# Remove the db.delete_table(), if you don't at Step 7 you'll likely get
# "django.db.utils.ProgrammingError: table "common_cat" does not exist"
# Leave existing db.alter_column() statements here
db.alter_column('common_toy', 'belongs_to_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['specific.KittyCat']))
def backwards(self, orm):
# Copy/paste the auto-generated db.alter_column()
# into the create_kittycat migration if you need backwards to work.
pass
# update_microchip_fk
class Migration(SchemaMigration):
...
def forwards(self, orm):
# Leave existing db.alter_column() statements here
db.alter_column('identity_microchip', 'identifies_id', self.gf('django.db.models.fields.related.OneToOneField')(to=orm['specific.KittyCat']))
def backwards(self, orm):
# Copy/paste the auto-generated db.alter_column()
# into the create_kittycat migration if you need backwards to work.
pass
Adım 6. Sadece çalışmak için geriye doğru () ihtiyacınız varsa VE geriye doğru çalışan bir KeyError alıyorsanız.
# the_one_before_create_kittycat
class Migration(SchemaMigration):
# You many also need to add more models to South's FakeORM if you run into
# more KeyErrors, the trade-off chosen was to make going forward as easy as
# possible, as that's what you'll probably want to do once in QA and once in
# production, rather than running the following many times:
#
# python manage.py migrate specific <the_one_before_create_kittycat>
models = {
...
# Copied from 'identity' app, 'update_microchip_fk' migration
u'identity.microchip': {
'Meta': {'object_name': 'Microchip'},
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
'identifies': ('django.db.models.fields.related.OneToOneField', [], {to=orm['specific.KittyCat']})
},
...
}
Adım 7. Test edin - benim için işe yarayan şeyler sizin gerçek yaşam durumunuz için yeterli olmayabilir :)
python manage.py migrate
# If you need backwards to work
python manage.py migrate specific <the_one_before_create_kittycat>