4👍
Update: with mysql-5.5.30-1.fc18.x86_64
and
MySQL-python==1.2.4
Django==1.4.2
South==0.7.6
the following works:
class Migration(SchemaMigration_:
def forwards(self, orm):
db.rename_column('app_model', 'old_id', 'new_id')
db.alter_column('app_model', 'new_id',
self.gf('django.db.models.fields.related.ForeignKey')(
blank=True,
null=True,
to=orm['app.OtherModel']
))
def backwards(self, orm):
db.rename_column('app_model', 'new_id', 'old_id')
db.alter_column('app_model', 'old_id',
self.gf('django.db.models.fields.related.ForeignKey')(
blank=True,
null=True,
to=orm['app.OtherModel']
))
As @Eloff comments, South can’t find the original FK for reasons unknown, but it doesn’t seem to matter. There is no need for a data migration (I believe) as pk values should not change.
The field specification (using self.gf
) is taken from South’s auto-generated migrations for consistency.
24👍
First, you need to use the db column name not the one in the model. Eg: foobar_id not foobar.
Then you need to drop the fk constraints and recreate them after renaming:
db.drop_foreign_key('app_model', 'old_id')
db.rename_column('app_model', 'old_id', 'new_id')
db.alter_column('app_model', 'new_id', models.ForeignKey(to=orm['app.OtherModel']))
If your fk is nullable you need to use change it to:
db.alter_column('app_model', 'new_id', models.ForeignKey(null=True, to=orm['app.OtherModel']))
- Combining two forms in one Django view
- How to add django rest framework permissions on specific method only ?
- How to get a name of last migration programmatically?
- Django server not sending logs to Logstash
11👍
MySQL users ought to be aware of this bug in south, if indeed it still applies:
http://south.aeracode.org/ticket/697
The workaround is to conduct the migration in 3 steps:
1) Add new field
2) data migrate the data to the new field
3) delete the old field
6👍
When renaming a ForeignKey
, remember to add _id
to the end of the field name you use in Django. E.g.
db.rename_column('accounts_transaction', 'operator_id', 'responsible_id')
And not
db.rename_column('accounts_transaction', 'operator', 'responsible')
But I have only tested this on sqlite (which don’t actually have the ALTER_TABLE at all), so I don’t know if it will actually work on mysql/postgres.