Django Error "django.db.utils.ProgrammingError: subquery has too many columns "

Django Error "django.db.utils.ProgrammingError: subquery has too many columns "

原始查询本身是正确的,我能够从数据库中检索原始查询集。我需要将其转换为查询集以进行进一步处理,但我遇到了以下错误。

创建相应的 Django 查询对我来说很难,这就是我创建 SQL 查询、获取原始查询集并现在尝试将其转换为查询集以供进一步处理的原因。

为了匿名,我更改了 django 模型名称和 table 名称。

这是我在 django 中尝试的结果 shell。我能够执行下面的查询,但是当我尝试访问下面的“queryset”时出现错误“django.db.utils.ProgrammingError:子查询有太多列”。

from django.db.models.expressions import RawSQL
from xyz.models import *
value = '1.2.3.4'
queryset = Test1.objects.filter(id__in=RawSQL("SELECT DISTINCT ON (test1.start_time, test1.id) test1.id, test1.name, test1.start_time FROM test1 WHERE EXISTS (SELECT * FROM test2 JOIN test3 ON test2.test3_id = test3.id AND test3.value = %s JOIN test4 ON test2.test4_id = test4.id AND test4.test1_id = test1.id) ORDER BY test1.start_time DESC", params=[value]))

为了便于阅读,我对下面使用的查询进行了格式化。

SELECT
  DISTINCT ON (test1.start_time, test1.id)
  test1.id,
  test1.name,
  test1.start_time
FROM
  test1
WHERE
  EXISTS (
    SELECT
      *
    FROM
      test2
      JOIN test3 ON test2.test3_id = test3.id
      AND test3.value = 'value'
      JOIN test4 ON test2.test4_id = test4.id
      AND test4.test1_id = test1.id
  )
ORDER BY
  test1.start_time DESC

如错误所述,您select过滤条件不需要的列过多。您的子查询必须 select 只有 Test1 table id 字段,因为您在 id 字段上进行过滤。所以基本上你的子查询应该只像这样投影 id 字段:

SELECT
  test1.id
FROM
  test1
WHERE
  EXISTS (
    SELECT
      *
    FROM
      test2
      JOIN test3 ON test2.test3_id = test3.id
      AND test3.value = 'value'
      JOIN test4 ON test2.test4_id = test4.id
      AND test4.test1_id = test1.id
  )
ORDER BY
  test1.start_time DESC

所以你的最终查询集应该是这样的:

queryset = Test1.objects.filter(id__in=RawSQL("SELECT test1.id FROM test1 WHERE EXISTS (SELECT * FROM test2 JOIN test3 ON test2.test3_id = test3.id AND test3.value = %s JOIN test4 ON test2.test4_id = test4.id AND test4.test1_id = test1.id) ORDER BY test1.start_time DESC", params=[value]))

您根本不需要 RawSQL

from django.db.models import Exists, OuterRef

queryset = Test1.objects.filter(
    Exists(Test2.objects.filter(
        test3__value=value,
        test4__test1_id=OuterRef('id')
    )
)

我不确定您的 Django 模型名称,因此 test3test4test1 在您的示例中可能略有不同。