Monday, October 20, 2014

Re: Django builds incorrect sql-query

On Mon, Oct 20, 2014 at 1:53 AM, Алексей Широков <alexi1988@gmail.com> wrote:
> SELECT ...
> FROM "document_document"
> INNER JOIN "document_sending" ON ("document_document"."id" =
> "document_sending"."document_id")
> INNER JOIN "document_sending" T4 ON ("document_document"."id" =
> T4."document_id")
> WHERE ("document_sending"."user_id" = 1
> AND T4."state" = 1)
> ORDER BY "document_document"."created" DESC
>
> Why...???
> it is incorrect!!!
>
> must be...
>
> SELECT ...
> FROM "document_document"
> INNER JOIN "document_sending" ON ("document_document"."id" =
> "document_sending"."document_id")
> WHERE ("document_sending"."user_id" = 1
> AND "document_sending"."state" = 1)
> ORDER BY "document_document"."created" DESC


From the docs [1]:
"To handle both of these situations, Django has a consistent way of
processing filter() and exclude() calls. Everything inside a single
filter() call is applied simultaneously to filter out items matching
all those requirements. Successive filter() calls further restrict the
set of objects, but for multi-valued relations, they apply to any
object linked to the primary model, not necessarily those objects that
were selected by an earlier filter() call."


in other words, your query is equivalent to:

Document.objects.filter(sendings__user=1).filter(sendings__state=0b0000001)

here, `sendings__user` and `sendings__state` appear on different
`filter()` calls, so each can refer to independent `Sending` objects.

try:

Document.objects.filter(sendings__user=1, sendings__state=0b0000001)

in this case, `sendings__user` and `sendings__state` appear on the
same `filter()` call, so they refer to `user` and `state` fields of
the same `Sending` object.


[1]: https://docs.djangoproject.com/en/1.7/topics/db/queries/#spanning-multi-valued-relationships

--
Javier

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/CAFkDaoRsD0ZAT4dp2UKu58SH2RC_rYL_s-VW6xV_HRXJTvbyrg%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment