Django 2.0:sqlite IntegrityError:FOREIGN KEY约束失败

时间:2017-12-03 16:25:08

标签: python django sqlite foreign-keys django-2.0

我正致力于为django-pagetree库添加Django 2.0支持。在自动化测试期间,使用sqlite内存数据库,我得到了一堆这样的错误:

  File "/home/nnyby/src/django-pagetree/pagetree/tests/test_models.py", line 638, in setUp
    'children': [],
  File "/home/nnyby/src/django-pagetree/pagetree/models.py", line 586, in add_child_section_from_dict

...

  File "/home/nnyby/src/django-pagetree/venv/lib/python3.5/site-packages/django/db/backends/base/base.py", line 239, in _commit
    return self.connection.commit()
django.db.utils.IntegrityError: FOREIGN KEY constraint failed

这在Django 2.0发行说明中有所说明:https://docs.djangoproject.com/en/2.0/releases/2.0/#foreign-key-constraints-are-now-enabled-on-sqlite

根据我不完全理解的描述,这不应该适用于不持久的测试数据库,对吧?使用Django 2.0时,不会使用适当的选项创建我的sqlite测试数据库吗?

我用于测试的应用设置位于:https://github.com/ccnmtl/django-pagetree/blob/master/runtests.py

8 个答案:

答案 0 :(得分:5)

文档说了两件事:

  1. 如果您有ForeignKey约束,它们现在在数据库级别强制执行。因此,请确保您没有违反外键约束。这是导致问题的最可能原因,但这意味着您已经在其他数据库中看到了这些问题。在代码中查找这样的模式:

    # in pagetree/models.py, line 810
    @classmethod
    def create_from_dict(cls, d):
        return cls.objects.create()  # what happens to d by the way?
    

    由于PageBlock必须section,因此肯定会因为ForeignKey约束错误而失败,因此您无需先指定create即可调用<ul class="top-section-list" data-selenium="highlightList"> <li class="top-section-list-item">sample text# 1</li> <li class="top-section-list-item">sample text# 2</li> <li class="top-section-list-item">sample text# 3</li> <li class="top-section-list-item">sample text# 4</li> <li class="top-section-list-item">sample text# 5</li> </ul>

    < / LI>
  2. 如果通过执行原子事务(例如)来延迟提交外键来绕过外键约束,则外键需要初始化为DEIDRED。实际上,您的测试数据库应该已经具有该功能,因为它每次都会重建。

答案 1 :(得分:0)

遇到相同情况的情况时,情况有所不同。问题是我使用相同的模型名称和字段名称

错误代码

class Column(models.Model):
    ...

class ColumnToDepartment(models.Model):
    column = models.ForeignKey(Column, on_delete=models.CASCADE)

解决方案

class Column(models.Model):
    ...

class ColumnToDepartment(models.Model):
    col = models.ForeignKey(Column, on_delete=models.CASCADE)

答案 2 :(得分:0)

我刚刚在我的Django项目中遇到了此错误:sqlite3.IntegrityError: FOREIGN KEY constraint failed。原来,我删除了该行中的某个地方的migrations文件夹,因此当我运行python manage.py makemigrations时,它没有收到我的模型更改。只要确保您仍然有一个包含迁移的迁移文件夹即可。

答案 3 :(得分:0)

还有另一件事要检查,就我而言,这与我的灯具文件有关。 迁移到Django3后重新生成它们可以解决我在测试应用程序时遇到的问题。

./manage.py dumpdata app.Model1 app.Model2 --indent=4 > ./app/fixtures/file.json

答案 4 :(得分:0)

当我在迁移或表方面遇到麻烦时,我会这样做,这通常会有所帮助:

  1. 注释您的麻烦字符串;
  2. 执行python3 manage.py makemigrationspython3 manage.py migrate
  3. 然后您必须执行python3 manage.py migrate --fake;
  4. 取消注释字符串,然后再次进行python3 manage.py makemigrationspython3 manage.py migrate

我希望它对您有用

答案 5 :(得分:0)

就我而言,我发现模型所引用的ForeignKey对象不存在。 这样我就可以将引用的FK对象更改为存在对象。

答案 6 :(得分:0)

我的问题在做迁移后解决了,因为我改变了外键,然后没有应用迁移。

具体来说,起初我在模型中有以下一段代码:

class TeacherRequest(models.Model):
    requester = models.ForeignKey(
        Profile,
        on_delete=models.CASCADE,
        related_name="teacher_request",
    )

    class RequestStatus(models.TextChoices):
        PENDING = '1', _('pending')
        APPROVED = '2', _('approved')
        REJECTED = '3', _('rejected')

    status = models.CharField(
        choices=RequestStatus.choices,
        max_length=1,
        default=RequestStatus.PENDING,
    )

然后我将外键从 Profile 改为 User


class TeacherRequest(models.Model):
    requester = models.ForeignKey(
        User,
        on_delete=models.CASCADE,
        related_name="teacher_request",
    )

    class RequestStatus(models.TextChoices):
        PENDING = '1', _('pending')
        APPROVED = '2', _('approved')
        REJECTED = '3', _('rejected')

    status = models.CharField(
        choices=RequestStatus.choices,
        max_length=1,
        default=RequestStatus.PENDING,
    )

解决方案

python manage.py makemigrations
python manage.py migrate

答案 7 :(得分:-1)