Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 437 Vote(s) - 3.43 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to see the raw SQL queries Django is running?

#1
Is there a way to show the SQL that Django is running while performing a query?
Reply

#2
Though you can do it with with the code supplied, I find that using the debug toolbar app is a great tool to show queries. You can download it from github [here](

[To see links please register here]

).

This gives you the option to show all the queries ran on a given page along with the time to query took. It also sums up the number of queries on a page along with total time for a quick review. This is a great tool, when you want to look at what the Django ORM does behind the scenes. It also have a lot of other nice features, that you can use if you like.
Reply

#3
Another option, see logging options in settings.py described by this post

[To see links please register here]


debug_toolbar slows down each page load on your dev server, logging does not so it's faster. Outputs can be dumped to console or file, so the UI is not as nice. But for views with lots of SQLs, it can take a long time to debug and optimize the SQLs through debug_toolbar since each page load is so slow.
Reply

#4
No other answer covers this method, so:

I find by far the most useful, simple, and reliable method is to ask your database. For example on Linux for Postgres you might do:

sudo su postgres
tail -f /var/log/postgresql/postgresql-8.4-main.log

Each database will have slightly different procedure. In the database logs you'll see not only the raw SQL, but any connection setup or transaction overhead django is placing on the system.
Reply

#5
[Django-extensions][1] have a command [shell_plus][2] with a parameter `print-sql`

./manage.py shell_plus --print-sql

In django-shell all executed queries will be printed

Ex.:

User.objects.get(pk=1)
SELECT "auth_user"."id",
"auth_user"."password",
"auth_user"."last_login",
"auth_user"."is_superuser",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."date_joined"
FROM "auth_user"
WHERE "auth_user"."id" = 1

Execution time: 0.002466s [Database: default]

<User: username>

[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#6
If you make sure your settings.py file has:

1. `django.core.context_processors.debug` listed in `CONTEXT_PROCESSORS`
2. `DEBUG=True`
3. your `IP` in the `INTERNAL_IPS` tuple

Then you should have access to the `sql_queries` variable. I append a footer to each page that looks like this:



{%if sql_queries %}
<div class="footNav">
<h2>Queries</h2>
<p>
{{ sql_queries|length }} Quer{{ sql_queries|pluralize:"y,ies" }}, {{sql_time_sum}} Time
{% ifnotequal sql_queries|length 0 %}
(<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.disp\
lay=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>)
{% endifnotequal %}
</p>
<table id="debugQueryTable" style="display: none;">
<col width="1"></col>
<col></col>
<col width="1"></col>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">SQL</th>
<th scope="col">Time</th>
</tr>
</thead>
<tbody>
{% for query in sql_queries %}
<tr class="{% cycle odd,even %}">
<td>{{ forloop.counter }}</td>
<td>{{ query.sql|escape }}</td>
<td>{{ query.time }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}

I got the variable `sql_time_sum` by adding the line

context_extras['sql_time_sum'] = sum([float(q['time']) for q in connection.queries])

to the debug function in django_src/django/core/context_processors.py.
Reply

#7
Take a look at **debug_toolbar**, it's very useful for debugging.

Documentation and source is available at

[To see links please register here]

.

[![Screenshot of debug toolbar][1]][1]

[1]:
Reply

#8
The following returns the query as valid SQL, based on

[To see links please register here]

:

def str_query(qs):
"""
qs.query returns something that isn't valid SQL, this returns the actual
valid SQL that's executed:

[To see links please register here]

"""
cursor = connections[qs.db].cursor()
query, params = qs.query.sql_with_params()
cursor.execute('EXPLAIN ' + query, params)
res = str(cursor.db.ops.last_executed_query(cursor, query, params))
assert res.startswith('EXPLAIN ')
return res[len('EXPLAIN '):]
Reply

#9
I've made a small snippet you can use:

from django.conf import settings
from django.db import connection


def sql_echo(method, *args, **kwargs):
settings.DEBUG = True
result = method(*args, **kwargs)
for query in connection.queries:
print(query)
return result


# HOW TO USE EXAMPLE:
#
# result = sql_echo(my_method, 'whatever', show=True)

It takes as parameters function (contains sql queryies) to inspect and args, kwargs needed to call that function. As the result it returns what function returns and prints SQL queries in a console.
Reply

#10
I developed an extension for this purpose, so you can easily put a decorator on your view function and see how many queries are executed.

To install:

$ pip install django-print-sql

To use as context manager:

from django_print_sql import print_sql

# set `count_only` to `True` will print the number of executed SQL statements only
with print_sql(count_only=False):

# write the code you want to analyze in here,
# e.g. some complex foreign key lookup,
# or analyzing a DRF serializer's performance

for user in User.objects.all()[:10]:
user.groups.first()

To use as decorator:

from django_print_sql import print_sql_decorator


@print_sql_decorator(count_only=False) # this works on class-based views as well
def get(request):
# your view code here

Github:

[To see links please register here]

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through