【问题标题】:You are trying to add a non-nullable field 'id' to contact_info without a default您正在尝试在没有默认值的情况下向 contact_info 添加不可为空的字段“id”
【发布时间】:2016-01-04 16:03:49
【问题描述】:

我正在使用命令python manage.py makemigrations

但是,我收到此错误:

You are trying to add a non-nullable field 'id' to contact_info
without a default; we can't do that (the database needs something to
populate existing rows). 
Please select a fix: 
1) Provide a one-off default now (will be set on all existing rows) 
2) Quit, and let me add a default in models.py

这里是models.py:

class Document(models.Model):
    docfile = models.FileField(upload_to='documents/')


class contact_number(models.Model):
    contact_numbers = models.CharField(max_length=13)

class contact_address(models.Model):
    address = models.CharField(max_length=100)
    city = models.CharField(max_length=50)
    state = models.CharField(max_length=50)
    zip = models.CharField(max_length=5)

class contact_info(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    email = models.EmailField()
    contact_numbers = models.ManyToManyField(contact_number)
    addresses = models.ManyToManyField(contact_address)

【问题讨论】:

  • 这是特定的,但我不知道如何更正此问题或将值放入 db。
  • 您之前是否设置了不同的字段作为主键?我很惊讶迁移正在尝试添加一个 id 字段。
  • 如果数据库中没有任何重要数据,那么最简单的方法可能是删除数据库并重新创建它,删除应用程序的所有迁移,然后重新运行 makemigrations
  • 我清除了数据库,然后重新启动syncdb,但错误仍然相同:(
  • 不要使用syncdb,它已被弃用。清除数据库,删除所有迁移,然后重新创建它们。

标签: django python-2.7 django-models


【解决方案1】:

检查您的迁移文件

./manage.py showmigrations <App Name>
[X] 0001_initial

[X] 0002_auto_20181204_1110

使用恢复您的迁移

./manage.py migrate <App Name> <migration file name>

例如:0001_initial

或使用零(用于完全迁移还原)

./manage.py migrate <App Name> zero

检查您的迁移

./manage.py showmigrations <App Name>
[ ] 0001_initial

[ ] 0002_auto_20181204_1110

现在删除所有还原迁移并再次迁移。

./manage.py migrate <App Name>

【讨论】:

    【解决方案2】:

    您恰好正在生成表之间的关系,您要做的就是在错误消息所指的表的字段之一中添加一个字段null = True(class contact_info).

    【讨论】:

      【解决方案3】:

      数据库需要一些东西来填充现有的行。 所以在这里你想为它定义一些值,你可以使用 default=""

       contact_info = models.CharField(default="" ,max_length=15)
      

      【讨论】:

        【解决方案4】:

        当一个不同的字段之前用primary_key=True 标记为主键并且您正在删除它时会发生这种情况(在这种情况下,django 会尝试添加一个id 主键)。

        Django 要求主键的默认值似乎是一个错误。

        要解决此问题,请按以下步骤操作:

        1. 在 makemigrations 期间出现提示时提供随机默认值。

        2. 转到生成的迁移文件(在your_app\migrations\ 下并删除default=x,,x 是您在步骤1 中提供的随机值。

        3. 当您在迁移文件中时,请确保操作顺序合理(例如,在添加另一个主键之前删除/更改一个主键)。保存并关闭。

        4. 照常迁移。

        【讨论】:

        • 是的,这就是问题和解决方案,看起来确实是一个错误,批准的解决方案是不正确的。
        • @mehmet 太好了!在尝试了许多其他事情之后,这种解决方法帮助我最终前进。看来这就是那个错误(code.djangoproject.com/ticket/22997)。但不幸的是,在执行上述操作后,另一个错误 (code.djangoproject.com/ticket/24030#comment:9) 暴露了。我必须完全删除数据库并重新运行所有迁移才能使用默认的 id 字段作为主键。
        【解决方案5】:

        在我看来,完全删除迁移是一个懒惰的坏主意。我做了一个类似于@Afiz Momin 的混乱,并且能够把自己挖出来。

        我有以下设置:

        1. 一个基本的抽象模型。
        2. 创建后覆盖 id 字段(坏主意)
        3. 所有其他子类触发 Django 迁移以尝试从父类创建 ID 字段。

        所以我会得到以下每次我运行makemigrations

        You are trying to add a non-nullable field 'id' to <tablename> without a default; we can't do that (the database needs something to populate existing rows).
        Please select a fix:
        1) Provide a one-off default now (will be set on all existing rows with a null value for this column)
        2) Quit, and let me add a default in models.py
        

        但有一条出路。

        在我的第一次尝试中,我只是在其中植入一个假值,然后删除创建的 id 列,但这显然是不可持续的。但一时兴起,我做了以下事情:

        1. 将迁移目录备份到migrations.orig
        2. 运行 ./manage.py makemigrations 进行所有迁移。
        3. 检查新创建的迁移文件0001-initial

        可能是它抱怨的模型 (&lt;tablename&gt;) 缺少重要信息。对我来说,它缺少 bases 参数:

        migrations.CreateModel(
            name='<ModelName>',
                fields=[
                    ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                    ('some_field', models.IntegerField()),
                    # ... other fields ...
                ],
                options={
                    'abstract': False,
                },
                bases=(<base_classes>),
            ),
        
        1. 现在返回 migrations.orig 并搜索迁移首次创建模型的位置。迁移线与上述类似。
        2. migrations.orig 中找到该行后,修改它以匹配新的迁移代码。
        3. 恢复您的原始迁移。删除migrations并将migrations.orig重命名为migrations
        4. 为了更好的衡量,运行./manage.py makemigrations./manage.py migrate。您应该不会再收到错误消息了!
        5. 如果它抱怨其他型号,请按照描述的相同程序进行操作。

        【讨论】:

          【解决方案6】:

          如果您在 models.py 中进行了一些更改并在之后尝试迁移,也会发生这种情况。发生在我身上一次。毕竟删除整个数据库并没有帮助。如果添加外键后出现错误,则不能提供默认值,或者将默认值设置为 null 可能不安全。

          可能 Django 在您的 myapp/migrations/ 文件夹中仍然有一些以前的迁移文件。删除这些文件可能会有所帮助。

          【讨论】:

            【解决方案7】:

            我在做 makemigration 时遇到了类似的问题。我的模型中有名为“Identity”的主键和其他字段,我应用了 makemigrations。后来,我将主键名称更改为“_id”,我得到了这个错误。

            您正在尝试在没有默认值的情况下向 swapidentity 添加不可为空的字段“_id”;我们不能这样做(数据库需要一些东西来填充现有的行)。

            错误有点误导,但是如果您将“_id”改回“身份”,您将不会收到该错误。

            如何解决? 删除迁移包下生成的迁移脚本。或者在生成的迁移脚本中手动更改主键。

            【讨论】:

              【解决方案8】:

              您可以设置 `default="" 和 editable=False。

              例如first_name = models.CharField(max_length=50, default="", editable=False)

              添加 id 字段是不必要的。 Django 会自动添加。

              编辑:删除迁移文件夹中的最后一个迁移文件,然后重试。如果它不起作用,请重复相同的过程,当您的“makemigrations”命令起作用时,您将知道您删除了正确的文件。

              【讨论】:

              • 我没有添加 id 字段。我想将此模型迁移到数据库中,但它显示了那些我不知道如何处理的消息。
              • 您是否先运行了syncdb 命令?运行 python manage.py syncdb 后运行 python manage.py makemigrations yourapp
              • 是的,它显示:没有要应用的迁移。您的模型具有尚未反映在迁移中的更改,因此不会应用。运行“manage.py makemigrations”进行新的迁移,然后重新运行“manage.py migrate”以应用它们。
              • 为什么不清空db,然后用syncdb重启。 python manage.py flush
              • mehmet 的回答解决了问题,而这只是做其他事情。 “添加id字段是不必要的。Django会自动添加它。”好吧,这就是问题所在,似乎在 Django 1.9 中没有。我也发生过。
              【解决方案9】:

              您需要设置一个默认值。例如:

              field_eg = models.CharField(default="")
              

              意思是:

              name = models.CharField(max_length=100, default="")
              

              【讨论】:

                【解决方案10】:

                这是因为您有非空数据库。肯定有没有通过Django ORM创建的行。

                执行以下操作: python manage.py shell

                from <path_to_your_models> import *
                print len(list(contact_info.objects.filter(id = None)))
                

                这样您就可以知道有多少这样的行。如果您想保留它们,只需使用您赋予它的一些值制作迁移脚本。

                【讨论】:

                • 我使用了 shell 并尝试在其中添加值,但它显示:>>> p1 = contact_number(contact_numbers='12345678') >>> p1.save() IntegrityError: myapp_contact_number.contact_id_id 可能不为 NULL 我如何才能删除 django 默认 ID 或访问 myapp_contact_number.contact_id_id
                猜你喜欢
                • 2020-06-03
                • 2017-10-09
                • 2020-07-12
                • 1970-01-01
                • 2021-11-16
                • 1970-01-01
                • 2021-08-25
                • 2021-09-06
                • 2020-03-28
                相关资源
                最近更新 更多