Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to view corresponding SQL query of the Django ORM's queryset?

People also ask

How do you get raw SQL query from Django?

Executing custom SQL directly The object django.db.connection represents the default database connection. To use the database connection, call connection.cursor() to get a cursor object. Then, call cursor.execute(sql, [params]) to execute the SQL and cursor.fetchone() or cursor.fetchall() to return the resulting rows.

How do I access QuerySet in Django?

You get a QuerySet by using your model's Manager . Each model has at least one Manager , and it's called objects by default. Access it directly via the model class, like so: >>> Blog.objects <django.db.models.manager.Manager object at ...> >>> b = Blog(name='Foo', tagline='Bar') >>> b.objects Traceback: ...

Can I filter a QuerySet Django?

The filter() method is used to filter you search, and allows you to return only the rows that matches the search term.


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.


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.


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())

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)

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.


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

tail -f /path/to/the/log/file.log

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() )