#34615 closed Bug (wontfix)
queryset.order_by().first() is not consistent with other queryset behaviours
Reported by: | Iuri de Silvio | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.2 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | yes |
Easy pickings: | no | UI/UX: | no |
Description
For any other operation, an empty .order_by()
remove default ordering, but it orders by pk
when .first()
is called.
>>> User.objects.only("pk").order_by()[:1] SELECT "auth_user"."id" FROM "auth_user" LIMIT 1
>>> User.objects.only("pk").order_by().first() SELECT "auth_user"."id" FROM "auth_user" ORDER BY "auth_user"."id" ASC LIMIT 1
I think it is an "undefined behavior" and it should build the query without ordering.
The ~almost~ undocumented implementation for this today should be:
try: user = User.objects.only("pk")[0] except IndexError: user = None
Change History (7)
comment:1 by , 18 months ago
Component: | Uncategorized → Database layer (models, ORM) |
---|---|
Type: | Uncategorized → Bug |
comment:2 by , 18 months ago
Has patch: | set |
---|
comment:3 by , 18 months ago
Patch needs improvement: | set |
---|
comment:4 by , 18 months ago
Resolution: | → wontfix |
---|---|
Status: | assigned → closed |
comment:5 by , 18 months ago
Thanks! I disagree a bit because if I'm explicitly disabling ordering with an empty order_by
, it is not the same as not defining ordering.
I'll follow up on mailing list.
comment:7 by , 18 months ago
Thanks! I disagree a bit because if I'm explicitly disabling ordering with an empty order_by, it is not the same as not defining ordering.
I get your original point, but I agree with Mariusz and the original authors adding this behaviour.
To have a first/last you must have deterministic ordering and not whatever the database feels like it wants to do otherwise this will start to introduce subtle soul-destroying bugs. I've numerous tests fail intermittently (with the same db) because we forgot to add explicit ordering.
We added
order_by("pk")
only when it's not explicitly ordered, mainly, to get the consistent and stable behavior on all backends. It's been that way basically forever and, IMO, we shouldn't change it. You can start a discussion on DevelopersMailingList if you don't agree.