I would like to view the queries run inside a block of code, ideally getting it as a list of strings.
Of course there are similar SO questions and answers, but they do not address my three specific requirements:
- Works for queries other than
SELECT
. - Works when the code is not in
DEBUG
mode. - The code executes normally, i.e. any production code runs as production code.
What I have so far is a transaction inside a DEBUG=True
override, that is instantly rolled back after the queries are collected.
from contextlib import contextmanager
from django.conf import settings
from django.db import connections
from django.db import transaction
from django.test.utils import override_settings
@contextmanager
@override_settings(DEBUG=True)
def print_query():
class OhNo(Exception):
pass
queries = []
try:
with transaction.atomic():
yield
for connection in connections:
queries.extend(connections[connection].queries)
print(queries)
raise OhNo
except OhNo:
pass
def do_special_debug_thing():
print('haha yes')
with print_query():
Foo.objects.update(bar=1)
if settings.DEBUG:
do_special_debug_thing()
There are two problems with that snippet:
- That
DEBUG
override doesn't do anything. The context manager prints out[]
. - If the
DEBUG
override is effective, thendo_special_debug_thing
is called, which I do not want to happen.
So, as far as I know, there is no way to collect all queries made inside a block of code, including those that are SELECT
statements, while DEBUG
is off. What ways are there to achieve this?