You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

捕获IntegrityError与创建对象前过滤:哪种方案更优?

问题:两种数据库对象创建方案哪种更优?

我有一项开发任务,需通过函数创建数据库对象,该函数接收第三方客户端请求返回的多个JSON对象。我遍历这些JSON对象,逐一调用_create_db_object方法创建对象。

示例模型:

class MyObject(models.Model):
   some_unique_field = models.CharField(unique=True)
   ...
   ...

当前创建对象的函数:

def _create_db_object(dict_: dict[str, str]) -> None:
    try:
        return MyObject.objects.create(...)
    except IntegrityError as e:
        continue

我想知道:改用以下先过滤再创建的函数是否更好?

def _create_db_object(dict_: dict[str, str]) -> None:
    if MyObject.objects.filter(some_unique_field=dict_["unique_field"]):
        continue

    return MyObject.objects.create(...)

哪种方案更优?原因是什么?


分析与结论

推荐使用第一种捕获IntegrityError的方案,原因如下:

  • 避免竞态条件:第二种方案的「查询-创建」是两步分离操作,高并发场景下可能出现多个请求同时通过查询(此时目标记录还不存在),随后同时执行创建操作,最终触发数据库唯一约束报错。而第一种方案直接依赖数据库的唯一约束做最终校验,创建操作是原子性的,不会出现这类问题。

  • 性能更高效:第二种方案每次创建前都要多执行一次查询;第一种方案只有在遇到重复数据时才会触发异常捕获,多数数据不重复的场景下,只需要一次创建操作,整体效率更高。

  • 代码更简洁可靠:第一种方案不需要额外编写查询逻辑,直接利用数据库本身的约束保证唯一性,代码更简洁,也符合依赖底层约束保障数据一致性的最佳实践。

只有在低并发且重复数据占比极高的极端场景下,第二种方案能减少异常抛出次数,但这种场景非常少见。绝大多数业务场景中,捕获IntegrityError的方案是更稳妥、高效的选择。

内容的提问来源于stack exchange,提问作者Burakhan Aksoy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 20:43:10