为什么Django查询要检查唯一性?
Why Does Django Query to Check Uniqueness?
tl;dr:为什么 Django 对 INSERT 的唯一性检查需要 SELECT 查询,我可以永久禁用它吗?
我正在努力高度优化正在写入 PSQL 数据库的 Django 应用程序。我有一个 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
字段的唯一性从不 检查。
这有效,我没有得到额外的查询。我还验证了如果我 do 尝试重新插入重复的 UUID,我确实会收到一个错误,将数据库作为源。
我的问题是:Django 为什么要这样做?我很想阻止 Django 检查唯一性 ever,除非到数据库的额外往返完成一些有价值的目的。
环境:
django==2.2.12
psycopg2-binary==2.8.5
在 Django 中,模型验证 与模型保存 是截然不同的步骤。看起来无论你在做什么都在触发验证。
将这些作为单独的步骤有很多充分的理由。一是与数据库约束相比,您可以在任意 Python 代码中表达更多的约束。另一个是它允许您生成比尝试解析 non-standardized 数据库错误时获得的描述性更多的错误消息。另一个是有时您只是想知道某些东西是否有效但不想实际保存它。
默认情况下,Django does not validate models 在保存它们之前。但是,一些 Django 组件,如管理员(更一般地,ModelForms
)会触发验证。
因此,您需要弄清楚为什么在您的情况下会触发验证,如果这不是您想要的,请阻止它。
tl;dr:为什么 Django 对 INSERT 的唯一性检查需要 SELECT 查询,我可以永久禁用它吗?
我正在努力高度优化正在写入 PSQL 数据库的 Django 应用程序。我有一个 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
字段的唯一性从不 检查。
这有效,我没有得到额外的查询。我还验证了如果我 do 尝试重新插入重复的 UUID,我确实会收到一个错误,将数据库作为源。
我的问题是:Django 为什么要这样做?我很想阻止 Django 检查唯一性 ever,除非到数据库的额外往返完成一些有价值的目的。
环境:
django==2.2.12
psycopg2-binary==2.8.5
在 Django 中,模型验证 与模型保存 是截然不同的步骤。看起来无论你在做什么都在触发验证。
将这些作为单独的步骤有很多充分的理由。一是与数据库约束相比,您可以在任意 Python 代码中表达更多的约束。另一个是它允许您生成比尝试解析 non-standardized 数据库错误时获得的描述性更多的错误消息。另一个是有时您只是想知道某些东西是否有效但不想实际保存它。
默认情况下,Django does not validate models 在保存它们之前。但是,一些 Django 组件,如管理员(更一般地,ModelForms
)会触发验证。
因此,您需要弄清楚为什么在您的情况下会触发验证,如果这不是您想要的,请阻止它。