django.db.utils.IntegrityError:

时间:2019-05-30 08:05:31

标签: django python-3.x

  

django.db.utils.IntegrityError:表'main_tutorial'中具有主键'1'的行具有无效的外键:main_tutorial.tutorial_series_id包含值'tutorial_series_id'在main_tutorialseries.id中没有对应的值

出现以上错误,无法迁移

这些是我的模特:

    from django.db import models
    from datetime import datetime
    #Create your models here.

    class TutorialCategory(models.Model):
        tutorial_category = models.CharField(max_length=200)
        category_summary = models.CharField(max_length=200)
        category_slug = models.CharField(max_length=200, default=1)

        class Meta:
            #Gives the proper plural name for admin
            verbose_name_plural = "Categories"

        def __str__(self):
            return self.tutorial_category

    class TutorialSeries(models.Model):
        tutorial_series = models.CharField(max_length=200)
        tutorial_category = models.ForeignKey(TutorialCategory, default=1,verbose_name="Category", on_delete=models.SET_DEFAULT)
        series_summary = models.CharField(max_length=200)

        class Meta:
            #Otherwise we get "Tutorial Serie*ss* in admin"
            verbose_name_plural = "Series"

        def __str__(self):
            return self.tutorial_series

    class Tutorial(models.Model):
        tutorial_title = models.CharField(max_length=200)
        tutorial_content = models.TextField()
        tutorial_published = models.DateTimeField("date published", default = datetime.now())
        tutorial_series = models.ForeignKey(TutorialSeries, default=1, verbose_name="Series", on_delete=models.SET_DEFAULT)
        tutorial_slug = models.CharField(max_length=200,default=1)

        def __str__(self):
            return self.tutorial_title

10 个答案:

答案 0 :(得分:8)

我也遇到了同样的问题。您要做的就是

只需从“ main()”和“ db.sqlite”文件中删除“ migrations”文件夹。

该错误可能是因为数据库中已经有Tutorial 它没有链接到TutorialSeries,所以使其链接到 db,进行上述更改,然后再次执行命令。

我得到的是:

python manage.py makemigrations

输出:

No changes detected

下一个

python manage.py migrate

输出:

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK

确保在执行这些命令时已链接了Tutorial 与TutorialSeries。而以这种方式完成工作的人会使您从数据库中丢失较早的数据。对此要小心。

祝您愉快,编码愉快。coding

答案 1 :(得分:2)

您可以简单地从django shell中删除main_tutorial表中的所有对象:

  1. 转到命令提示符
  2. python manage.py shell
  3. from main.models import Tutorial
  4. Tutorial.objects.all().delete()

(此处主要是应用名称)

这将删除Tutorial表中的所有对象,然后进行迁移和迁移,并且应该可以正常工作。

答案 2 :(得分:0)

在您的 Tutorial 模型中,您正在使用外键字段** tutorial_series **的默认值。这将导致迁移检查TutorialSeriesid=1中的记录是否存在,但是不存在此类数据,因此会发生错误。

为避免迁移时出错,请从我们的字段中删除on_delete=models.SET_DEFAULTdefault=1,以使模型成为:

class TutorialSeries(models.Model):
    tutorial_series = models.CharField(max_length=200)
    tutorial_category = models.ForeignKey(TutorialCategory,verbose_name="Category")
    series_summary = models.CharField(max_length=200)

    class Meta:
        #Otherwise we get "Tutorial Serie*ss* in admin"
        verbose_name_plural = "Series"

    def __str__(self):
        return self.tutorial_series

class Tutorial(models.Model):
        tutorial_title = models.CharField(max_length=200)
        tutorial_content = models.TextField()
        tutorial_published = models.DateTimeField("date published", default = datetime.now())
        tutorial_series = models.ForeignKey(TutorialSeries, verbose_name="Series", blank=True, null=True) #<--changes
        tutorial_slug = models.CharField(max_length=200,default=1)

        def __str__(self):
            return self.tutorial_title

此后,迁移模型。然后使用id=1将数据添加到 TutorialCategory TutorialSeries

然后将模型恢复为初始设置(保留默认值= 1,并且on_delete = models.SET_DEFAULT)。然后再次运行makemigrations并迁移模型。之后,您的问题可能会解决。

答案 3 :(得分:0)

尝试在没有默认参数的情况下使用on_delete = models.CASCADE

答案 4 :(得分:0)

我正在处理同一问题。我删除了迁移中的所有内容,除了_init__.py和sqlite数据库之外。然后运行-3.7 manage.py makemigrations,然后执行py -3.7 manage.py migration。然后成功了!

答案 5 :(得分:0)

尝试删除除__init__.py以外的所有迁移文件,同时还要删除db.sqlite3。之后,运行makemigrations并再次迁移

答案 6 :(得分:0)

我前一段时间遇到这个问题。 上面的答案可能是正确的,但对我没有用,因为 -im使用postgres,我不能只删除数据库 -migration文件是在git中提交的。

我的情况是,我有004个迁移文件,但由于IntegrityError而无法运行它。

我检查了文件,发现它在operation列表中。

列表的第一项是migrations.CreateModel,第二项是migrations.AddField

这是我的步骤:

  1. 评论了列表中的第二项,仅剩下CreateModel

  2. 然后运行migrate

  3. 打开Django管理页面并手动添加缺少的ID 您也可以在数据库编辑器或update语句中添加它。

  4. 取消对AddField部分的注释,然后重新运行migrate

答案 7 :(得分:0)

from django.db import models
from datetime import datetime


class TutorialCategory(models.Model):
    tutorial_category = models.CharField(max_length=200)
    category_summary = models.CharField(max_length=200)
    category_slug = models.CharField(max_length=200)

    class Meta:
        verbose_name_plural = "Categories"

    def __str__(self):
        return self.tutorial_category

class TutorialSeries(models.Model):
    tutorial_series = models.CharField(max_length=200)
    tutorial_category = models.ForeignKey(TutorialCategory, verbose_name="Category", on_delete=models.CASCADE, blank=True, null=True)
    series_summary = models.CharField(max_length=200)

    class Meta:
        verbose_name_plural = "Series"

    def __str__(self):
        return self.tutorial_series

class Tutorial(models.Model):
    tutorial_title = models.CharField(max_length=200)
    tutorial_content = models.TextField()
    tutorial_published = models.DateTimeField('date published', default=datetime.now)

    tutorial_series = models.ForeignKey(TutorialSeries, verbose_name="Series", on_delete=models.CASCADE, blank=True, null=True)
    tutorial_slug = models.CharField(max_length=200, default=1)

    def __str__(self):
        return self.tutorial_title

尝试一下,对我有用。

但是请记住,在完成“ python3 manage.py makemigrations”和“ python3 manage.py migration”之前,您需要输入以下代码

答案 8 :(得分:-1)

以下答案由好人发布在senddex的Django教程评论中:“ Kevin di”和“ JOSEPH Blessingh”。该建议对我有帮助,并且像魅力一样起作用:

工作目录中有一个文件“ db.sqlite3”,您可以使用任何支持SQLite类型的数据库管理工具来打开它。 请按照以下步骤操作:

  1. 例如,“用于SQLite的数据库浏览器”,您可以通过Google下载并下载。
  2. 打开“ db.sqlite3”文件,导航到表。
  3. 找到main_tutorial表。 (也许您在上一课中使用了另一个表名,请使用表名。)
  4. 从表中删除记录:main_tutorial。
  5. 尝试python manage.py再次迁移。

从表中删除记录的含义可以解释为: -点击main_tutorial -然后,您可能会看到一个名为“浏览数据”的标签 -单击它,您将看到您的记录 -在左侧列的数字上按Ctrl +鼠标左键以选择所有行 -右键单击即可删除它们

答案 9 :(得分:-1)

从文件夹中删除迁移文件

__init__.py

然后:

python manage.py makemigrations
python manage.py migrate