#28664 closed Uncategorized (duplicate)
basic subquery generates invalid sql
Reported by: | David Szotten | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
from django.db import models class Foo(models.Model): a = models.IntegerField() b = models.IntegerField() class Bar(models.Model): foo = models.ForeignKey(Foo, on_delete=models.CASCADE)
>>> print(Bar.objects.filter(foo=Foo.objects.filter(a=1)).query) SELECT "app_bar"."id", "app_bar"."foo_id" FROM "app_bar" WHERE "app_bar"."foo_id" = (SELECT U0."id", U0."a", U0."b" FROM "app_foo" U0 WHERE U0."a" = 1)
The subquery is selecting all columns, causing django.db.utils.ProgrammingError: subquery must return only one column
Change History (4)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
Resolution: | → duplicate |
---|---|
Status: | new → closed |
Duplicate of #28497. Using __eq=queryset
was never officially supported. You can use __in=queryset
or __eq=queryset.values('field')
to work around the issue.
comment:3 by , 7 years ago
ah, my mistake, apologies.
though in that case, i wonder if it would be possible to provide more helpful error message instead of generating bad sql and sending to the db
comment:4 by , 7 years ago
The current consensus in #28497 would be to officialize the support of __eq=queryset
.
Note that there won't be any way from protecting you from passing a queryset returning more than a single result and ending up with a more than one row returned by a subquery used as an expression
or similar message from the database. You'll have to make sure the provided filters don't match more than a single row or that you LIMIT
your query.
looks like it broke with https://github.com/django/django/commit/ec50937bcbe160e658ef881021402e156beb0eaf