您试图在没有默认值的情况下向contact_info添加不可为空的字段“id”

时间:2015-10-07 12:16:45

标签: python django python-2.7 django-models

我只是使用简单的命令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)

10 个答案:

答案 0 :(得分:23)

当一个不同的字段被标记为早期url(r'^(?P<question_id>[0-9]+/$)', views.detail, name='detail'), 的主键并且您要删除它时(如果django尝试添加primary_key=True主键),就会发生这种情况。

django要求主键的默认值似乎是一个bug。

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

1)在makemigrations期间提示时提供随机默认值。

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

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

4)像往常一样迁移。

答案 1 :(得分:4)

你可以设置`default =“”并且editable = False。

E.g first_name = models.CharField(max_length=50, default="", editable=False)

不需要添加id字段。 Django会自动添加它。

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

答案 2 :(得分:1)

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

field_eg = models.CharField(default="")

表示:

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

答案 3 :(得分:0)

这种情况正在发生,因为您有非空的数据库。必须有一条尚未通过Django ORM创建的行。

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

-- Sample data.
declare @Table1 as Table ( Id Int, LabelName VarChar(10), LabelValue VarChar(10) );
insert into @Table1 ( Id, LabelName, LabelValue ) values
  ( 1, 'x', 'c1' ), ( 1, 'y', 'c1' ), ( 1, 'a', 'c2' ),
  ( 2, 'y', 'c1' ), ( 2, 'a', 'c2' ),
  ( 3, 'a', 'c2' ),
  ( 4, 'j', 'c3' );
select * from @Table1;

declare @Table2 as Table ( CustId VarChar(10), LabelName VarChar(10), LabelValue VarChar(10) );
insert into @Table2 ( CustId, LabelName, LabelValue ) values
  ( 'cust1', 'b', 'xx' ), ( 'cust1', 'x', 'c1' ), ( 'cust1', 'y', 'c1' ), ( 'cust1', 'a', 'c2' ),
  ( 'cust2', 'a', 'c3' ), ( 'cust2', 'x', 'c1' ),
  ( 'cust3', 'j', 'c3' );
select * from @Table2;

-- Run the query.
select T1.Id, T2.CustId
  from @Table1 as T1 inner join
    @Table2 as T2 on T2.LabelName = T1.LabelName and T1.LabelValue = T2.LabelValue
  group by T1.Id, T2.CustId
  having Count( T1.Id ) = ( select Count( Id ) from @Table1 where Id = T1.Id )

通过这种方式,您可以找到有多少这样的行。如果你想保留它们只是使迁移脚本具有一些你给它的值。

答案 4 :(得分:0)

我在进行移民时遇到了类似的问题。我的主键是名字&#39; Identity&#39;和我应用makemigrations的模型中的其他字段。后来,我将主键名更改为&#39; _id&#39;我收到了这个错误。

  

您正在尝试添加一个不可为空的字段&#39; _id&#39;在没有违约的情况下交换身份;我们不能这样做(数据库需要填充现有行的东西)。

错误有点误导,但是如果你改回来了_id到身份&#39;你不会得到那个错误。

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

答案 5 :(得分:0)

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

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

答案 6 :(得分:0)

在我看来,完全删除迁移是一个懒惰和坏主意。我做了类似于@Afiz Momin的snafu,能够发现自己。

我进行了以下设置:

  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

机会是它抱怨(<tablename>)缺少重要信息的模型。对我来说,它缺少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. 如果投诉其他型号,请遵循上述相同步骤。

答案 7 :(得分:0)

检查您的迁移文件

./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 showmigrations <App Name>

[] 0001_initial

[] 0002_auto_20181204_1110

现在删除所有还原迁移,然后再次迁移。

./manage.py migrate <App Name>

答案 8 :(得分:0)

数据库需要一些东西来填充现有行。 因此,您要在此处定义一些值,可以使用default =“”

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

答案 9 :(得分:0)

您恰好在表之间生成关系,您需要做的是在错误消息所引用的表的其中一个字段中添加一个字段null = True,{<1>} }