Opened 16 years ago
Closed 16 years ago
#9997 closed (fixed)
Nested queries support: Field for ValuesListQuerySet (flat=True) gets lost in query construction
Reported by: | Matthias Kestenholz | Owned by: | Malcolm Tredinnick |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | dev |
Severity: | 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
I have a model called Favorite which has a generic foreign key. I want to get all bookmarked jobs for a user efficiently, therefore I query the database for all object_ids:
ids = Favorite.objects.get_favorites_by_model(Job).filter(user=1).values_list('object_id', flat=True) In [28]: ids Out[28]: [338L, 308L, 212L, 345L, 307L, 264L, 322L, 354L, 326L, 328L, 335L, 334L, 332L, 353L, 352L, 351L, 350L, 349L, 316L] In [33]: type(ids) Out[33]: <class 'django.db.models.query.ValuesListQuerySet'>
Now, using this information I want to get a list of all jobs. However, the following two statements yield completely different results. Only the former is correct:
In [22]: Job.objects.filter(id__in=tuple(ids)) Out[22]: [<Job.... In [20]: Job.objects.filter(id__in=ids) Out[20]: [<Job....
The two corresponding SQL statements are:
{'sql': u'SELECT jobs_job
.id
, jobs_job
.created
, jobs_job
.modified
, jobs_job
.created_by_id
, jobs_job
.name
, jobs_job
.notes
, jobs_job
.job_id
, jobs_job
.customer_id
, jobs_job
.contact_id
, jobs_job
.project_id
, jobs_job
.state
, jobs_job
.manager_id
, jobs_job
.no_profit
, jobs_job
.prepayment
, jobs_job
.archived_on
FROM jobs_job
WHERE jobs_job
.id
IN (338, 308, 212, 345, 307, 264, 322, 354, 326, 328, 335, 334, 332, 353, 352, 351, 350, 349, 316) ORDER BY jobs_job
.job_id
DESC LIMIT 21',
'time': '0.001'}
{'sql': u'SELECT jobs_job
.id
, jobs_job
.created
, jobs_job
.modified
, jobs_job
.created_by_id
, jobs_job
.name
, jobs_job
.notes
, jobs_job
.job_id
, jobs_job
.customer_id
, jobs_job
.contact_id
, jobs_job
.project_id
, jobs_job
.state
, jobs_job
.manager_id
, jobs_job
.no_profit
, jobs_job
.prepayment
, jobs_job
.archived_on
FROM jobs_job
WHERE jobs_job
.id
IN (SELECT U0.id
FROM favorites_favorite
U0 WHERE (U0.content_type_id
= 20 AND U0.user_id
= 1 )) ORDER BY jobs_job
.job_id
DESC LIMIT 21',
'time': '0.001'}
Note how the subquery selects the primary key instead of the object_id.
Change History (4)
comment:1 by , 16 years ago
Component: | Uncategorized → Database layer (models, ORM) |
---|
comment:2 by , 16 years ago
Version: | 1.0 → SVN |
---|
comment:3 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
Hmm. Good point. This opens a whole other bag of worms for how people are going to use and abuse nested queries, too. Time to insert a bunch of error messages along with some fixes.
comment:4 by , 16 years ago
Resolution: | → fixed |
---|---|
Status: | assigned → closed |
(sorry for the spam, will try to correctly set the ticket properties from the start next time)