Django为什么要查询以检查唯一性



tl;dr:为什么Django对INSERT的唯一性检查需要SELECT查询,我可以永久禁用它吗

我正在努力高度优化Django应用程序,该应用程序正在编写PSQL数据库。我有一个uuid列,它是作为模型一部分的primary_key。它是模型中唯一的unique字段。

id = models.UUIDField(
primary_key = True,
default = uuid.uuid4,
editable = False,
null = False,
blank = False,
help_text = 'The unique identifier of the Node.'
)

我遇到的问题是,当尝试save一个新项目时,Django会在insert:之前自动执行唯一性检查查询

SELECT (1) AS "a" FROM "customer" WHERE "customer"."id" = '1271a1c8-5f6d-4961-b2e9-5e93e450fd4e'::uuid  LIMIT 1

这会导致额外的数据库往返行程。我知道字段必须是唯一的,但Django当然已经在数据库级别配置了这一点,所以如果它试图insert一个具有非唯一字段的行,它会得到一个错误。

我已经实现了一个变通方法,通过在我的model:中添加以下内容来抑制查询

def validate_unique(self, *args, **kwargs):
# Make sure that we never validate if ID is unique. Duplicates OK.
current_exclude = set(kwargs.get('exclude', []))
current_exclude.add('id')
kwargs['exclude'] = list(current_exclude)
super().validate_unique(*args, **kwargs)

这将确保id字段的唯一性从不检查

这是有效的,我没有得到额外的查询。我还验证了,如果我确实尝试重新插入一个重复的UUID,那么我确实会以数据库为源出现错误。

我的问题是:Django为什么要这么做?我很想阻止Django检查唯一性,除非额外的DB往返行程实现了一些有价值的目的。

环境:

django==2.2.12
psycopg2-binary==2.8.5

在Django中,模型验证是与保存模型不同的步骤。看起来,无论你在做什么,都会触发验证。

有许多充分的理由使这些步骤成为单独的步骤。一个是,在任意Python代码中可以表达比数据库约束多得多的约束。另一个原因是,它允许您生成比解析非标准化数据库错误更多的描述性错误消息。另一个是,有时你只是想知道某个东西是否有效,但不想真正保存它

默认情况下,Django在保存模型之前不会对其进行验证。不过,一些Django组件,比如admin(更一般地说,ModelForms(确实会触发验证。

所以,你需要弄清楚为什么在你的情况下会触发验证,如果这不是你想要的,就阻止它

最新更新