Sandesh Veerapur
Sandesh Veerapur

Reputation: 51

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

The raw query itself is correct and I am able to get retrieve the rawqueryset from the db. I need to convert this into queryset for further processing and I am facing below error.

Creating corresponding django query was hard for me and that is why I created SQL query, got the raw query set and now attempting to convert it to query set for further processing.

I have changed django model names and table names for anonymity.

Here is the output of what I tried in django shell. I was able to execute the below query but getting the error "django.db.utils.ProgrammingError: subquery has too many columns" when I try to access "queryset" below.

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]))

For readability I have formatted the query used below.

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

Upvotes: 0

Views: 2656

Answers (2)

Brad Martsberger
Brad Martsberger

Reputation: 1967

You don't need the RawSQL at all

from django.db.models import Exists, OuterRef

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

I'm not certain your django model names, so test3, test4, and test1 may be a little different in your example.

Upvotes: 1

Mahender Thakur
Mahender Thakur

Reputation: 510

As the error states, you are selecting too many columns which your filter condition does not require. You subquery must select only Test1 table id field as you filter on id field. So basically you subquery should only project id field like this:

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

So your final queryset should be like:

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]))

Upvotes: 2

Related Questions