【问题标题】:Django AutoField default value errorDjango AutoField 默认值错误
【发布时间】:2015-02-17 09:10:01
【问题描述】:

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?

【问题讨论】:

    标签: mysql django python-2.7 database-migration


    【解决方案1】:

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

    --fake 将告诉 Django 假装它运行了迁移并且它不会再次尝试运行它。

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

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

    【讨论】:

    • --fake 是最新的迁移号还是有问题的迁移号?以后我每次迁移这个应用程序时都需要使用该标志吗?
    • --fake 应该只在有问题的那个上运行,即你告诉它这个字段再次是主键的那个。在那之后,Django 不应该再打扰你了。
    • 成功了!另外,感谢有关确保现实与剩余 SQL 一致的警告。
    • 现在我密切相关但不重叠的问题是如何避免错误先验 - 即添加一个id 列(或自动添加一个)到已填充超过 0 行的现有表。它提示我输入一个默认值,但我知道这是导致我最初困惑的陷阱。
    • @webdevbyjoss 不。我放弃了寻找,因为我有一个解决方法,但我仍然很好奇。
    【解决方案2】:

    您不能在 MySQL 中设置自动增量列的默认值。

    您必须更改您的数据库表架构。问题是您的主键“id”(由 Django 自动生成)具有 Auto Increment =“True”。由于自动增量为真,因此您无法将默认值设置为 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

    【讨论】:

    • 那条 SQL 的 AI 默认值是 Django 生成的。我确实删除了defaultauto_increment,但问题是确实具有这些功能的旧化石迁移继续抛出异常,因为它是后续依赖项的目标。
    • 您是否在迁移前同步您的数据库? python manage.py syncdb
    • @planet260 OP 正在使用 Django 1.7 的迁移
    【解决方案3】:

    primary_key不能有这个默认参数,所以你应该删除这个默认参数。

    【讨论】:

    • 一定是评论
    • 也不必加粗
    猜你喜欢
    • 2016-02-01
    • 2017-07-31
    • 2022-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-27
    • 2011-11-22
    • 2017-06-06
    相关资源
    最近更新 更多