Search code examples
mysqldjangopython-2.7database-migration

Django AutoField default value error


Django 1.7.1, MySQL 5.6, Python 2.7.8

I had a model that looked like this:

class Host(models.Model):
    hostName = models.CharField(max_length=45, primary_key=True)
    ...

I removed primary_key=True manually, which caused manage.py sqlmigrate to show that the primary key was being dropped, an autoincrementing 'id' column was being added, and it was getting the primary key. I was prompted for a default value for the new 'id' column, and mistakenly gave it 1, which was already in the table. The relevant SQL read:

ALTER TABLE `Host` ADD COLUMN `id` integer AUTO_INCREMENT DEFAULT 1 NOT NULL PRIMARY KEY;

and the migration code included:

    operations = [
    migrations.AddField(
        model_name='host',
        name='id',
        field=models.AutoField(auto_created=True, primary_key=True, default=1, serialize=False, verbose_name='ID'),
        preserve_default=False,
    ),

The result was that I can still modify my models and makemigrations works, but each migrate command gives this error:

django.db.utils.OperationalError: (1067, "Invalid default value for 'id'")

and does not take effect.

I've tried reverting the primary key change, manually pointing the immediately subsequent migration at the immediately previous migration (which raised consistency problems), and migrating explicitly to the immediately previous migration. What I would really like to do is simply erase/ignore the problem migration. I would also be satisfied with suppressing the error since I have since reverted the change. How can I do either of these?

Edit: Also, if an autoincrement column can never have a default value why does Django allow itself to pass the SQL with ...AUTO_INCREMENT DEFAULT 1...?


Solution

  • You can fix the error in SQL (if you haven't already) and then just run ./manage.py migrate [your_app_name] [the_migration_number] --fake

    The --fake will tell Django to pretend it ran the migration and it will not try to run it again.

    Just be sure that the changes you make in SQL are accurately reflected in the fake migration, because Django does not compare the models to the database when you run makemigrations.

    Regarding the error about the id column, if I remember correctly, you cannot assign a default value to a mysql auto increment field.