views:

103

answers:

2

I would like to change a name of specific fields in a model:

class Foo(models.Model):
    name = models.CharField()
    rel  = models.ForeignKey(Bar)

should change to:

class Foo(models.Model):
    full_name     = models.CharField()
    odd_relation  = models.ForeignKey(Bar)

What's the easiest way to do this using South?

+5  A: 

You can use the db.rename_column function.

class Migration:

    def forwards(self, orm):
        # Rename 'name' field to 'full_name'
        db.rename_column('app_foo', 'name', 'full_name')




    def backwards(self, orm):
        # Rename 'full_name' field to 'name'
        db.rename_column('app_foo', 'full_name', 'name')
googletorp
That would work on name\full_name, but not on the relation field, right?
Jonathan
I tried db.rename_column('app_foo', 'rel', 'odd_relation') and received:_mysql_exceptions.OperationalError: (1025, "Error on rename of '.\\ap_site\\#sql-1034_20' to '.\\my_app_db\\app_foo' (errno: 150)")
Jonathan
Turns out that this error is because there are indexes bonding this column (django generated unique_together constraints). Any idea how to continue from here?
Jonathan
wouldnt --auto pick this up?
Dave
IMPORTANT NOTE: if you're going to use this, make sure "app_foo" is the database table name, so for example: "mainapp_profile", "name" is the old column name of the database (not the model field name), for example: "user_id" and "full_name" would be the new name you want the column to have (again, database column and not field name). So:db.rename_column('mainapp_profile', 'user_id', 'new_user_id')Also, if you're dealing with foreign keys, you should have the "_id" part in them when renaming.
Pilgrim
A: 

I didn't know about db.rename column, sounds handy, however in the past I have added the new column as one schemamigration, then created a datamigration to move values into the new field, then a second schemamigration to remove the old column

dysmsyd
Me too. The problem with the schema-data-schema technique is that you end up with different names for your fields/models. Sometimes this is a problem if you use canonical names to enable dispatchers...
Jonathan
I just tried this and it didn't work as there was a name conflict. I had exact same FK but different name. It didn't validate. So, _don't_ do this.
Pilgrim
@jonathan, he wants different names!... @pilgrim, care to post some code? I have done this several times this week, if your models don't validate then south wont create the migrations.
dysmsyd