我有一个我想重命名的模型,但也改变了它的数据。模型字段,例如foo
包含字符数据1
... 6
,我想以下列方式映射此数据:
1
,2
- > 1
&& 3
,4
- > 2
&& 5
- > 3
&& 6
- > 4
我在我的应用上convert_to_south
创建了0001_initial
,然后更改了models.py
中的新新字段,并schemamigration
创建了0002_initial.py
。现在我该如何修改现有数据?以下是我的迁移:
0001_initial
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Applicant'
db.create_table(u'registrar_applicant', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('registered_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('workshop', self.gf('django.db.models.fields.CharField')(max_length=20)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('semester', self.gf('django.db.models.fields.CharField')(max_length=1)),
('python_experience', self.gf('django.db.models.fields.CharField')(max_length=1)),
('phone_number', self.gf('django.db.models.fields.CharField')(max_length=10, blank=True)),
('email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('solved_puzzle', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal(u'registrar', ['Applicant'])
def backwards(self, orm):
# Deleting model 'Applicant'
db.delete_table(u'registrar_applicant')
models = {
u'registrar.applicant': {
'Meta': {'ordering': "['-solved_puzzle', 'registered_at', 'semester', 'name']", 'object_name': 'Applicant'},
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '10', 'blank': 'True'}),
'python_experience': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'registered_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'semester': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'solved_puzzle': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'workshop': ('django.db.models.fields.CharField', [], {'max_length': '20'})
}
}
complete_apps = ['registrar']
0002_initial
class Migration(SchemaMigration):
def forwards(self, orm):
# Adding model 'Applicant'
db.create_table(u'registrar_applicant', (
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('registered_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
('workshop', self.gf('django.db.models.fields.CharField')(max_length=20)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('year', self.gf('django.db.models.fields.CharField')(max_length=1)),
('python_experience', self.gf('django.db.models.fields.CharField')(max_length=1)),
('phone_number', self.gf('django.db.models.fields.CharField')(max_length=10, blank=True)),
('email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('solved_puzzle', self.gf('django.db.models.fields.BooleanField')(default=False)),
))
db.send_create_signal(u'registrar', ['Applicant'])
def backwards(self, orm):
# Deleting model 'Applicant'
db.delete_table(u'registrar_applicant')
models = {
u'registrar.applicant': {
'Meta': {'ordering': "['-solved_puzzle', 'registered_at', 'year', 'name']", 'object_name': 'Applicant'},
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'phone_number': ('django.db.models.fields.CharField', [], {'max_length': '10', 'blank': 'True'}),
'python_experience': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'registered_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'solved_puzzle': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'workshop': ('django.db.models.fields.CharField', [], {'max_length': '20'}),
'year': ('django.db.models.fields.CharField', [], {'max_length': '1'})
}
}
complete_apps = ['registrar']
答案 0 :(得分:1)
为此,您必须创建data migration
# Run this command from the shell
python manage.py datamigration <app_name> change_foo_values
这将创建一个名为0003_change_foo_values.py
的迁移文件。您必须手动编辑该文件。
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(DataMigration):
def forwards(self, orm):
"Write your forwards methods here."
# Note: Don't use "from appname.models import ModelName".
# Use orm.ModelName to refer to models in this application,
# and orm['appname.ModelName'] for models in other applications.
orm.Applicant.objects.filter(foo__in=['1', '2']).update(foo='1')
orm.Applicant.objects.filter(foo__in=['3', '4']).update(foo='2')
orm.Applicant.objects.filter(foo__in=['5', '6']).update(foo='3')
def backwards(self, orm):
"Write your backwards methods here."
# This migration cannot be reversed
pass # don't do anything when running reverse migration
# or
raise RuntimeError("Cannot reverse this migration") # stop south from reverting beyond this migration
注意:您无法恢复到以前的列值。如果这不是问题那么这就足够了。
但是,如果您确实希望能够撤消迁移,我建议您创建一个新字段,该字段将保留每行的旧值。
PS:您的迁移文件似乎有误。您不应该为一个应用程序进行两次initial
次迁移。在重命名模型(似乎没有重命名)之后,您是否再次运行convert_to_south
?最初将现有模型转换为南时,您只需运行convert_to_south
一次。之后,您需要创建schema migrations。最简单的方法是使用appname运行schemamigration
管理命令,并将--auto
作为参数。
python manage.py schemamigration <app_name> --auto
PPS:如果您想重命名模型,请创建一个空迁移并自行编写迁移代码,只需使用db.rename_table
即可。如果您在重命名模型后尝试创建自动架构迁移,则IIRC将在创建新表之前删除旧表。
python manage.py schemamigration <app_name> --empty rename_model_x_to_y
并在您的迁移文件中
# -*- coding: utf-8 -*-
from south.utils import datetime_utils as datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
class Migration(SchemaMigration):
def forwards(self, orm):
"Write your forwards methods here."
# Note: Don't use "from appname.models import ModelName".
# Use orm.ModelName to refer to models in this application,
# and orm['appname.ModelName'] for models in other applications.
db.rename_table('old', 'new')
def backwards(self, orm):
"Write your backwards methods here."
db.rename_table('new', 'old')