181

Is there a way I can print the query the Django ORM is generating?

Say I execute the following statement: Model.objects.filter(name='test')

How do I get to see the generated SQL query?

Underoos
  • 3,734
  • 6
  • 30
  • 63

8 Answers8

210

Each QuerySet object has a query attribute that you can log or print to stdout for debugging purposes.

qs = Model.objects.filter(name='test')
print(qs.query)

Note that in pdb, using p qs.query will not work as desired, but print(qs.query) will.

If that doesn't work, for old Django versions, try:

print str(qs.query)

Edit

I've also used custom template tags (as outlined in this snippet) to inject the queries in the scope of a single request as HTML comments.

Scott Stafford
  • 41,977
  • 23
  • 122
  • 172
Joe Holloway
  • 26,963
  • 15
  • 79
  • 92
121

You also can use python logging to log all queries generated by Django. Just add this to your settings file.

LOGGING = {
    'disable_existing_loggers': False,
    'version': 1,
    'handlers': {
        'console': {
            # logging handler that outputs log messages to terminal
            'class': 'logging.StreamHandler',
            'level': 'DEBUG', # message level to be written to console
        },
    },
    'loggers': {
        '': {
            # this sets root level logger to log debug and higher level
            # logs to console. All other loggers inherit settings from
            # root level logger.
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False, # this tells logger to send logging message
                                # to its parent (will send if set to True)
        },
        'django.db': {
            # django also has database level logging
            'level': 'DEBUG'
        },
    },
}

Another method in case application is generating html output - django debug toolbar can be used.

Gregor
  • 4,176
  • 1
  • 21
  • 37
aisbaa
  • 8,774
  • 5
  • 31
  • 43
  • 3
    If somebody would like to have **summary with sumup** of **number of executed queries** as well **total time** it took: http://www.dabapps.com/blog/logging-sql-queries-django-13/ – andilabs May 13 '15 at 10:07
  • 11
    It did not work for me, I had to add `'level': 'DEBUG'` under `'django.db'`. – rvernica Nov 18 '16 at 19:16
114

You can paste this code on your shell which will display all the SQL queries:

# To get all sql queries sent by Django from py shell
import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
Pramod
  • 5,000
  • 3
  • 41
  • 43
77

As long as DEBUG is on:

from django.db import connection
print(connection.queries)

For an individual query, you can do:

print(Model.objects.filter(name='test').query)
Jordan
  • 30,837
  • 6
  • 53
  • 65
Daniel Roseman
  • 567,968
  • 59
  • 825
  • 842
30

Maybe you should take a look at django-debug-toolbar application, it will log all queries for you, display profiling information for them and much more.

Mikhail Korobov
  • 21,149
  • 8
  • 72
  • 64
  • 4
    This is very useful, but it only works in the GUI and sometimes you want to see query logs directly in ORM. e.g. you have an api , with no GUI! – wim Sep 27 '16 at 15:06
3

A robust solution would be to have your database server log to a file and then

tail -f /path/to/the/log/file.log
alan
  • 2,950
  • 1
  • 31
  • 34
2

If you are using database routing, you probably have more than one database connection. Code like this lets you see connections in a session. You can reset the stats the same way as with a single connection: reset_queries()

from django.db import connections,connection,reset_queries
...
reset_queries()  # resets data collection, call whenever it makes sense

...

def query_all():
    for c in connections.all():
        print(f"Queries per connection: Database: {c.settings_dict['NAME']} {c.queries}")

# and if you just want to count the number of queries
def query_count_all()->int:
    return sum(len(c.queries) for c in connections.all() )
Tim Richardson
  • 5,237
  • 6
  • 37
  • 60
0

You can use a Django debug_toolbar to view the SQL query. Step by step guide for debug_toolbar usage :

Install the Debug_toolbar

pip install django-debug-toolbar

Edit settings.py file & add debug_toolbar to Installed apps, this should be added below to 'django.contrib.staticfiles'. Also add debug_toolbar to Middleware.

Settings.py=>

INSTALLED_APPS= [ 'debug_toolbar'] 

MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware']

create a new list named INTERNAL_IPS in settings.py file

Settings.py=> create new list at the end of settings.py file & add below list:

INTERNAL_IPS= [127.0.0.1']

This will allow the debug to run only on internal developement server

Edit urls.py file of #Project & add below code:

if settings.DEBUG:
    import debug_toolbar
    urlpatterns = [
    url(r'^__debug__/', include(debug_toolbar.urls))       
    ] + urlpatterns

apply migrate & run server again

You will see an add-on on your web page at 127.0.0.1 & if you click on SQL Query check box, you can actually see the run time of query as well.

Devesh G
  • 111
  • 10