【问题标题】:Duplicate save in Django transaction causing InternalError instead of IntegrityError在 Django 事务中重复保存导致 InternalError 而不是 IntegrityError
【发布时间】:2013-01-10 04:31:41
【问题描述】:

我使用 PostgreSQL 作为 psycopg2 的后端,我注意到一些对我来说似乎很奇怪的东西。我的设置如下:

class ParentModel(models.Model):
    field1 = models.IntegerField()

class ChildModel(ParentModel):
    field2 = models.IntegerField(unique=True)

当我尝试从 shell 保存具有重复字段 2 的 ChildModel 对象时,我得到的是 InternalError 而不是 IntegrityError,但如果保存是在 transaction.commit_on_success 块中完成的,像这样:

with transaction.commit_on_success():
    newObj = ChildModel(field1=5, field2=10) # Assume that a ChildModel with field2 == 10 exists 

如我所料,在事务块之外,我得到了一个 IntegrityError。

在视图代码中运行时,即使使用保存点,我也总是在更新失败后收到 InternalError:

try:
    sid = transaction.savepoint()
    newObj = ChildModel(field1=5, field2=10) # Assume that a ChildModel with field2 == 10 exists
    transaction.savepoint_commit(sid)
except IntegrityError:
    transaction.savepoint_rollback(sid)
except InternalError:
    transaction.savepoint_rollback(sid)

... other stuff ... # raises InternalError on next database hit

如果我在带有块的 commit_on_success 事务中执行此操作,而不是使用保存点,也会发生同样的事情。我安装了 TransactionMiddleware,但我没有在自动提交模式下运行 PostgreSQL。

我可以通过简单地检查以确保不存在重复对象来避免这种情况,但我想了解我对 Django 事务的理解出了什么问题。什么给了?

【问题讨论】:

    标签: django transactions django-views django-orm


    【解决方案1】:

    我遇到了完全相同的问题。我查看了 Postgres 日志文件,可以看到在导致完整性错误的查询之后正在运行另一个查询,这导致实际错误在默认事务设置中黯然失色。我发现额外的查询来自django-debug-toolbar app。

    Google 将我指向 https://github.com/django-debug-toolbar/django-debug-toolbar/issues/351,这似乎可以解决问题。

    简而言之,如果您使用的是 django-debug-toolbar

    【讨论】:

    • 我已经有一段时间没有弄乱这段代码了,所以我不确定这是否解决了上述问题。但是感谢您的提醒!
    猜你喜欢
    • 2020-04-01
    • 1970-01-01
    • 2012-09-09
    • 1970-01-01
    • 1970-01-01
    • 2018-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多