Opened 2 years ago

Closed 2 years ago

#30482 closed Bug (fixed)

prefetch_related_objects evaluates queryset when checking for invalid prefetch ordering.

Reported by: Iain P. Watts Owned by: Iain P. Watts
Component: Database layer (models, ORM) Version: dev
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When encountering a prefetch it has already seen and checking whether to throw the "lookup was already seen with a different queryset" ValueError, prefetch_related_objects will inadvertently evaluate lookup.queryset. For example:

foo = Foo.objects.create()
prefetches = [
    'bar',
    Prefetch('bar', queryset=Bar.objects.filter(my_field=True))
]
prefetch_related_objects([foo], *prefetches)

Right before it throws the ValueError, the above code will execute the full unfiltered query Bar.objects.filter(my_field=True). This may match a very large number of rows (or a whole table), since it is not restricted to Bars related to the specific foo. In our case this led to the query timing out and the page returning a 504 without the code ever actually reaching the ValueError.

Change History (6)

comment:1 Changed 2 years ago by Iain P. Watts

Owner: set to Iain P. Watts

comment:2 Changed 2 years ago by Iain P. Watts

Type: UncategorizedBug

comment:3 Changed 2 years ago by Iain P. Watts

Has patch: set

comment:5 Changed 2 years ago by Mariusz Felisiak

Summary: prefetch_related_objects evaluates lookup.queryset when checking for invalid prefetch orderingprefetch_related_objects evaluates queryset when checking for invalid prefetch ordering.
Triage Stage: UnreviewedAccepted
Version: 2.2master

comment:6 Changed 2 years ago by Mariusz Felisiak <felisiak.mariusz@…>

Resolution: fixed
Status: assignedclosed

In 59ffafa1:

Fixed #30482 -- Prevented unnecessary evaluation of lookup.queryset in prefetch_related_objects().

Note: See TracTickets for help on using tickets.
Back to Top