sql - Django When(...) object SQL 与 __in 一起使用时缺少 SQL,空列表作为值,导致 ProgrammingError
问题描述
使用 Django 3.0(将升级)我得到一些导致 a 的无效 SQL,django.db.utils.ProgrammingError
我想知道是否有人可以帮助我了解原因。
我想知道这个问题是否也出现在较新版本的 Django 中。但我希望在不必立即升级 Django 的情况下让它工作。
查询模型我正在为每个实例注释一个字段,并使用Case
它When
,并且似乎在使用带有查找空列表作为值的否定Q
对象时发生错误。__in
我将展示三个非常相似但导致不同 SQL 的示例。只有第一个示例会导致错误的 SQL。
导致无效 SQL 的示例查询:
Activity.objects.all()
.annotate(
employee_authorized=Case(
When(~Q(case__assigned_unit__in=[]), then=Value(False)),
default=Value(True),
output_field=BooleanField(),
)
)
这将导致以下 SQL,其中WHEN
和之间没有任何内容THEN
。这导致一个django.db.utils.ProgrammingError
.
SELECT "activity_activity"."id",
...
CASE WHEN THEN False ELSE True END AS "employee_authorized"
FROM "activity_activity"
LEFT OUTER JOIN "case_case" ON ("activity_activity"."case_id" = "case_case"."id")
下面的例子似乎导致了逻辑 SQL。唯一的区别是Q
对象没有被否定。
Activity.objects.all()
.annotate(
employee_authorized=Case(
When(Q(case__assigned_unit__in=[]), then=Value(False)),
default=Value(True),
output_field=BooleanField(),
)
)
SQL:
SELECT "activity_activity"."id",
...
True AS "employee_authorized"
FROM "activity_activity"
LEFT OUTER JOIN "case_case" ON ("activity_activity"."case_id" = "case_case"."id")
另一个确实导致逻辑 SQL 的示例,虽然否定Q
对象,但使用非空列表。
Activity.objects.all()
.annotate(
employee_authorized=Case(
When(~Q(case__assigned_unit__in=[OrgUnit.objects.first()]), then=Value(False)),then=Value(False)),
default=Value(True),
output_field=BooleanField(),
)
)
这导致以下SQL:
SELECT "activity_activity"."id",
...
CASE
WHEN NOT ("case_case"."assigned_unit_id" IN (251) AND "case_case"."assigned_unit_id" IS NOT NULL) THEN False
ELSE True END AS "employee_authorized"
FROM "activity_activity"
LEFT OUTER JOIN "case_case" ON ("activity_activity"."case_id" = "case_case"."id")
所以。我看不出我在这里做错了什么或是否做错了什么。希望有人可以帮助我完成这项工作。
解决方案
One idea to avoid this happening is to "switch" the default condition and use Q() instead of ~Q()
.annotate(
employee_authorized=Case(
When(Q(case__assigned_unit__in=[]), then=Value(True)),
default=Value(False),
output_field=BooleanField(),
)
)
推荐阅读
- javascript - 使用 Web Audio Api AudioWorklet 从音频流中抓取比特并进行 BPM 检测
- xamarin - Xamarin Forms:转换器的多个项目
- javascript - 仅在来自特定页面时创建该链接
- sql - 使用两个标准查找查询中的差异
- c# - ASP NET Web API google 身份验证问题 HTTP 404
- r - R Markdown 在代码块中使用“Eval”崩溃
- emacs - 如何将变量传递给 kbd 函数?
- javascript - CSS Grid: how to target CSS Grid cell using CSS or JavaScript
- java - 无法在项目 X 上执行目标:无法解析项目 X:jar:0.0.1-SNAPSHOT 的依赖项:找不到工件 XX:jar:0.0.1-SNAPSHOT
- php - QuickBooks Desktop Web 连接器自动运行请求队列