Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force evaluate a lazy query

Tags:

python

django

Is there a way to evaluate the following expression?

instances = Catalog.objects.filter(q)

I am trying to profile it, but since it is lazy, it won't actually do the evaluation until it returns it. I was thinking list(instances), is there anything else?

like image 425
David542 Avatar asked Mar 05 '15 22:03

David542


2 Answers

Here are all the ways to evaluate a lazy queryset. Using list is one of them:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#when-querysets-are-evaluated

like image 123
Selcuk Avatar answered Nov 07 '22 06:11

Selcuk


Using list() will evaluate the query, retrieve all of its results, and add all of the data to the QuerySet's cache. That's potentially a lot of overhead if you're not actually planning to use the data.

You could instead use Catalog.objects.filter(q).exists() (see exists), which does not need to fetch the entire result set. Just note that it executes a different query, which will look something like this, depending on your DBMS:

SELECT (1) AS "a" FROM "..._catalog" LIMIT 1;

If you want to evaulate a query that is closer to what you'd originally be executing, you could do something like:

try:
    Catalog.objects.filter(q)[0]
except IndexError:
    pass

That will still add a LIMIT or TOP to your query, but at least your query will still include all the columns and orderings and such that your original query would have.

You might be tempted to do something like bool(Catalog.objects.filter(q)) or otherwise use the QuerySet in a boolean context, but note that that will behave as list(), fetching the entire set of results.

like image 38
HorsePunchKid Avatar answered Nov 07 '22 05:11

HorsePunchKid