【问题标题】:IntegrityError in TestCase runs after updating to Django 2.0TestCase 中的 IntegrityError 在更新到 Django 2.0 后运行
【发布时间】:2018-12-31 14:05:16
【问题描述】:

我从 Django 1.11 升级到 Django 2.0,我的测试开始失败。我有 7 个 TestCase 类,并且都使用 Django 提供的 setUpTestData。当我一起运行它们时,其中一个由于psycopg2.IntegrityError: duplicate key value violates unique constraint "doctors_doctor_pkey" 而无法设置。

当我单独运行其中一个 TestCase 类时,它运行良好。似乎它们在某种程度上相互影响,但奇怪的是升级到 Django 2.0 后它会失败。我还注意到它不在create(),而是在save()。

在dashboards 应用程序的设置中,我有一些创建数据:

cls.d1 = doctor_models.Doctor.objects.create(email="johndoe@example.com", name="John Doe",
                                                 specialization=cls.s1, premium=True,
                                                 premium_price=4310, consultation_price=341)

...
cls.b1 = doctor_models.DoctorBooking.objects.create(clinic=cls.c1, doctor=cls.d1,
                                                            status=2, premium_booking=True,
                                                            patient_name="example",
                                                            patient_phone_number="+9747721234",
                                                            confirmed_date=datetime.strptime(
                                                                "16 Jun 2017 14:22:26:000 +0300",
                                                                receive_format),
                                                            handled_on=datetime.strptime(
                                                                "17 Jun 2017 14:22:26:000 +0300",
                                                                receive_format))

上面的第二行将调用它的 save() 函数,该函数将在 cls.d1 上调用 save()

def save(self, *args, **kwargs):
    if self.doctor.premium:
        self.premium_booking = True
    else:
        self.premium_booking = False
    super(DoctorBooking, self).save(*args, **kwargs)
    self.doctor.save()  # <- here it raises an IntegrityError

这是我可以提取的最简单的代码,但是对于不同的类,这都会发生。

重申这一点给了我以下内容。

psycopg2.IntegrityError: duplicate key value violates unique constraint "doctors_doctor_pkey"
DETAIL:  Key (id)=(7) already exists.

我什至不确定为什么会这样。当你创建一个对象时,psycopg2 不应该注意自动递增pk 吗?据我所知,数据库没有任何问题,当我在.save() 之前添加一个断点并检查数据库时,一个具有相同数据的医生和pk 已经在数据库中。所以我猜这是假设这两个对象是不同的......但我调用创建然后保存而不是创建两次。

编辑:在 cmets 中解决:D

【问题讨论】:

  • 顺便说一句,您为什么在保存模型后尝试保存医生?

标签: django postgresql django-2.1


【解决方案1】:

很可能,引用的doctor 已经保存。在尝试重新保存之前检查一下。

类似这样的:

def save(self, *args, **kwargs):
    if self.doctor.premium:
        self.premium_booking = True
    else:
        self.premium_booking = False

    super(DoctorBooking, self).save(*args, **kwargs)

    if not self.doctor.pk:
        self.doctor.save()

【讨论】:

  • 感谢您的回复!但为什么这很重要?我还需要救医生。在 Django 1.11 中,这工作正常。您还有其他想法吗?
  • 在您可以在另一个对象(此处为 DoctorBooking)中添加对任何对象(此处为医生)的引用之前,您必须在数据库中拥有该对象(此处为医生)。所以在你调用 DoctorBooking 的 save 之前,医生必须已经在数据库中,你已经在做 cls.d1= ... ,那你为什么要再次尝试保存医生?
  • 因为每次有新的预约时医生的排名都会发生变化,所以当我使用信号时也会发生同样的事情。当我尝试使用update_fields 时,它会中断,因为它在数据库中找不到它......所以我不知道
  • 所以我猜你需要更新医生的等级,你在哪里做呢?
  • 我已经发现了问题所在,和这个完全无关。那是另一回事。基本上 Django 试图在save 中创建一个新对象,因为它找不到具有相似 PK 的对象。这是因为 Doctor 有自己的经理 get_queryset,它只返回一组基于某些东西的医生,并且它没有返回具有相似 PK 的医生,所以它会发生冲突。最后一件事,我会为你的帮助点赞,你能否点赞我以超过 15 次代表的限制。
猜你喜欢
  • 1970-01-01
  • 2022-12-04
  • 2018-06-17
  • 1970-01-01
  • 2018-05-17
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多