Opened 16 years ago
Closed 16 years ago
#10352 closed (invalid)
Query.as_sql() breaks annotations
Reported by: | Glenn Maynard | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.0 |
Severity: | Keywords: | ||
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Calling as_sql() on a query with annotations breaks the query later. This is particularly annoying because it's a delayed effect. Repro attached.
ProgrammingError: missing FROM-clause entry for table "U0"
LINE 1: ...em"."creator_id", "queries_item"."note_id", COUNT("U0"."id")...
Attachments (1)
Change History (8)
by , 16 years ago
Attachment: | 10352-test.diff added |
---|
comment:1 by , 16 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:3 by , 16 years ago
Oh, right.. I understand the difference now. The patch is using QuerySet.as_sql()
, not Query.as_sql()
.
Question for the original reporter: is this report part of some larger problem? What are you actually doing that triggers this? I'm guessing a nested query of some kind, which is probably fine, but I'd like some confirmation.
Normally, you shouldn't ever be calling
QuerySet.as_sql()
. In fact, I'm fairly likely to change the name prior to Django 1.1 to indicate it's a true internal method (currently the name makes some other code a bit simpler, but the cost in inadvertent usability mistakes is probably too high, on reflection).
comment:4 by , 16 years ago
So far, just for examining specific queries when debugging. It only started showing problems after a trunk update. Is there a method to get the resulting SQL query (as far as is known so far, anyway) without unwanted side-effects on the object itself?
comment:5 by , 16 years ago
@Glenn: I think what you're looking for is QuerySet.query.as_sql().
As Malcolm has noted, as_sql() on a QuerySet is an internal method that is used to manipulate a QuerySet so it can be used for subquery evaluation - it actually changes the queryset into a ValuesQuerySet. It is not intended to be public API. If calling QuerySet.as_sql()
appeared to be working previously, it was almost certainly an accidental result stemming from the bugs that were recently closed.
In the test case you provided, lines 1049-50 should read:
>>> test = Item.objects.annotate(cnt=Count("id")) >>> test.query.as_sql()
This asks Django for the underlying query that will extract the data from the database; since it is an SQL query, the as_sql()
call on the underlying query will render that query as the SQL + parameters that will be sent to the database.
The problem as reported is therefore an invalid report; however, I'll leave this open as a marker to Malcolm about renaming as_sql()
so that others don't mistakenly use that method as public API.
comment:6 by , 16 years ago
comment:7 by , 16 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Something weird going on here. The query printed out by
test.as_sql()
in your failing example doesn't look even close to the right query (there's no "count" bit there).