Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to rename a foreignkey field with South?

Renaming a simple charfield etc seems easy (Django - How to rename a model field using South?)

However when I try using the same on a ForeignKey field I get an error:

_mysql_exceptions.OperationalError: (1091, "Can't DROP '[new_fkey_field_name]'; check that column/key exists")

Which stems from the migration trying to run the backwards for some reason (as evidenced in the trace).

Any ideas?

like image 710
GJ. Avatar asked Aug 14 '10 21:08

GJ.


3 Answers

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']))
like image 137
3 revs, 3 users 79% Avatar answered Oct 15 '22 23:10

3 revs, 3 users 79%


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

like image 25
Yeago Avatar answered Oct 16 '22 01:10

Yeago


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.

like image 6
Sindre R Myren Avatar answered Oct 15 '22 23:10

Sindre R Myren