Django AutoField默认值错误

时间:2014-12-18 14:36:00

标签: mysql django python-2.7 database-migration

Django 1.7.1,MySQL 5.6,Python 2.7.8

我有一个看起来像这样的模型:

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

我手动删除了primary_key=True,这导致manage.py sqlmigrate显示主键被删除,正在添加自动增量'id'列,并且它正在获取主键。我被提示输入新'id'列的默认值,并错误地给它1,这已经在表中。相关的SQL读取:

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

并包含迁移代码:

    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,
    ),

结果是我仍然可以修改我的模型和makemigrations工作,但每个migrate命令都会出现此错误:

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

并且不会生效。

我尝试恢复主键更改,手动指向上一次迁移时的紧接后续迁移(这会引发一致性问题),并明确迁移到上一次迁移。 我真正想要做的只是擦除/忽略问题迁移。我也会对抑制错误感到满意,因为我已经恢复了更改。我该怎么办?

修改 另外,如果自动增量列永远不能有默认值,为什么Django允许自己使用...AUTO_INCREMENT DEFAULT 1...传递SQL?

3 个答案:

答案 0 :(得分:6)

您可以修复SQL中的错误(如果您还没有),然后运行./manage.py migrate [your_app_name] [the_migration_number] --fake

--fake将告诉Django假装它运行迁移,它不会再尝试再运行它。

请确保您在SQL中所做的更改准确地反映在虚假迁移中,因为当您运行makemigrations时,Django不会将模型与数据库进行比较。

关于id列的错误,如果我没记错的话,你不能为mysql自动增量字段分配一个默认值。

答案 1 :(得分:0)

您无法在MySQL中为自动增量列设置默认值。

您必须更改数据库表架构。问题是您的主键“id”(由Django自动生成)具有自动增量=“真”。当自动增量为真时,您无法将默认值设置为1.每次运行迁移脚本时都会因此而抛出错误

例如,如果您运行以下查询

ALTER TABLE YOU_TABLE CHANGE id id INT(11) AUTO_INCREMENT NOT NULL DEFAULT 1;

它会抛出错误

MySQL Database Error: Invalid default value for 'id'    1

因此,您必须将主键更改为没有默认值。

ALTER TABLE YOU_TABLE CHANGE id id INT(11) AUTO_INCREMENT NOT NULL;

这样会更改架构,您将不再收到此错误。

同样在Django中你可以像这样设置默认值

column = models.CharField(max_length=7, default='0000000', editable=False)

对于Django参考:https://docs.djangoproject.com/en/dev/ref/models/fields/#editable StackOverflow问题:Default value for field in Django model

答案 2 :(得分:-1)

primary_key无法使用此默认参数,因此您应删除此默认参数。