Django migrations throw 1072 - key column 'car_make_id' doesn't exist in table
Question: Here's simplified task and setup (Django 1.8, MySQL, Python 2.7), I've got:

    
    
    class Car(models.Model):
        make = models.ForeignKey(CarMake)
    
    class Bike(models.Model):
        make = models.ForeignKey(BikeMake)
    
    class CarMake(models.Model):
        name = models.CharField(max_length=32)
    
    class BikeMake(models.Model):
        name = models.CharField(max_length=32)
    

Now, I need to ditch the **BikeMake** model completely so I update the
**CarMake** model with values from **BikeMake** and also update the foreign
key relationship in **Bike**.

I've created the following migration, which updates the **CarMake** with names
from **BikeMake** , adds temporary field **Bike.car_make** , migrates data
from **Bike.make** to **Bike.car_make** , removes the **Bike.make** field and
renames **Bike.car_make** to **Bike.make**.

    
    
    # -*- coding: utf-8 -*-
    from __future__ import unicode_literals
    from django.db import models, migrations
    
    
    def update_car_makes(apps, schema_editor):
        """Update CarMakes with BikeMakes"""
        BikeMake = apps.get_model('my_app', 'BikeMake')
        CarMake = apps.get_model('my_app', 'CarMake')
    
        for item in BikeMake.objects.all():
            if not CarMake.objects.filter(name=item.name).exists():
                CarMake.objects.create(name=item.name)
    
    
    def remove_car_makers(apps, schema_editor):
        """Restore original CarMake (exclude BikeMake)"""
        pass
    
    
    def migrate_to_car_make(apps, schema_editor):
        """Set Bike.car_make according to Bike.make"""
        CarMake = apps.get_model('my_app', 'CarMake')
        Bike = apps.get_model('my_app', 'Bike')
        for item in Bike.objects.all():
            old_make = item.make
            new_make = CarMake.objects.get(name=old_make.name)
            item.car_make = new_make
            item.save()
    
    
    def reverse_migrate_to_car_make(apps, schema_editor):
        pass
    
    
    def dummy_forwards(apps, schema_editor):
        # Empty forward migration needed for having custom backwards migration
        pass
    
    
    def restore_make_column_data(apps, schema_editor):
        BikeMake = apps.get_model('products', 'BikeMake')
        Bike = apps.get_model('products', 'Bike')
    
        for item in Bike.objects.all():
            old_make = item.bike_make
            new_make = BikeMake.objects.get(name=old_make.name)
            item.make = new_make
            item.save()
    
    
    class Migration(migrations.Migration):
    
        dependencies = [('my_app', '0001_blah_blah')]
    
        operations = [
            migrations.RunPython(
                update_car_makers,
                reverse_code=remove_car_makers
            ),
            migrations.AddField(
                model_name='bike',
                name='car_make',
                field=models.ForeignKey(default=1, to='my_app.CarMake'),
                preserve_default=False
            ),
            migrations.RunPython(
                migrate_to_car_make,
                reverse_code=reverse_migrate_to_car_make
            ),
            migrations.RunPython(
                dummy_forwards,
                reverse_code=restore_make_column_data
            ),
            migrations.RemoveField(
                model_name='bike',
                name='make',
            ),
            migrations.RenameField(
                model_name='bike',
                old_name='car_make',
                new_name='make'
            )
        ]
    

And when I try to run it, I get the #1072 error on running the last operation:
`migrations.RenameField`. Now the interesting part is that from DB POV
everything is complete, data migrated, column renamed, only the migration
isn't marked as done and error is thrown.

Also if I just move the `migrations.RenameField` to a separate migration file
and run two migrations in a row – everything works fine and it doesn't raise
the #1072 error.

In addition, I've tried inserting a breakpoint just before the
`migrations.RenameField` and I verified that **Bike.car_make** column exists
and I can fetch normally all objects of **Bike** model at that point.

The MySQL query, that results in error is following:

    
    
    CREATE INDEX `my_app_bike_c2036163` ON `my_app_bike` (`car_make_id`)
    

Any ideas how to fix it and have it within one migration file? Thanks in
advance!

**UPDATE 04.02.16**

As @kvikshaug pointed out, this happens because Django creates indexes and
constraints after performing all operations i.e. raw SQL for creating index
and/or constraints is generated at the time, the corresponding operation is
executed (in my case `AddField`), but that query is actually run at the very
end, thus the error.

One possible solution for relatively small schemas could be to use Django's
[`RunSQL`](https://docs.djangoproject.com/en/1.9/ref/migration-
operations/#runsql) and type the raw queries yourself, but that's quite
cumbersome + you've got to create constraints yourself.

So I went with separating the renaming migration.


Answer: Django migrations create indexes after performing all operations. Your second
operation, adding field `car_make`, makes Django add the `CREATE INDEX`
command which you noted causes the error:

    
    
    CREATE INDEX `my_app_bike_c2036163` ON `my_app_bike` (`car_make_id`)
    

**Even though you later renamed the field, Django still tries to create the
index for the now-missing`car_make` field, that's why you get the error.** You
can see this clearly by running `sqlmigrate`:

    
    
    $ ./manage.py sqlmigrate my_app 0002_blah_blah
    BEGIN;
    --
    -- MIGRATION NOW PERFORMS OPERATION THAT CANNOT BE WRITTEN AS SQL:
    -- Raw Python operation
    --
    --
    -- Add field car_make to bike
    --
    ALTER TABLE "my_app_bike" ADD COLUMN "car_make_id" integer DEFAULT 1 NOT NULL;
    ALTER TABLE "my_app_bike" ALTER COLUMN "car_make_id" DROP DEFAULT;
    --
    -- MIGRATION NOW PERFORMS OPERATION THAT CANNOT BE WRITTEN AS SQL:
    -- Raw Python operation
    --
    --
    -- MIGRATION NOW PERFORMS OPERATION THAT CANNOT BE WRITTEN AS SQL:
    -- Raw Python operation
    --
    --
    -- Remove field make from bike
    --
    ALTER TABLE "my_app_bike" DROP CONSTRAINT "my_app_bike_make_id_5615ed11_fk_my_app_bikemake_id";
    ALTER TABLE "my_app_bike" DROP COLUMN "make_id" CASCADE;
    --
    -- Rename field car_make on bike to make
    --
    ALTER TABLE "my_app_bike" RENAME COLUMN "car_make_id" TO "make_id";
    CREATE INDEX "my_app_bike_78e8ca60" ON "my_app_bike" ("car_make_id");
    ALTER TABLE "my_app_bike" ADD CONSTRAINT "my_app_bike_car_make_id_6c42be09_fk_my_app_carmake_id" FOREIGN KEY ("car_make_id") REFERENCES "my_app_carmake" ("id") DEFERRABLE INITIALLY DEFERRED;
    
    COMMIT;
    

You could try to report this as a bug (or search; maybe it's already
reported), but you're probably best off following Alasdairs suggestion and
just separate the migrations.

