Django, how to see sql query when running tests?

One of my django unit test applications crashes with

DatabaseError: ORA-00942: table or view does not exist 

I would like to see the actual SQL query that caused this error. Do you know how to achieve this?

+10
source share
6 answers

The best solution I've found so far is the jugo debugsqlshell management command provided by django-debugtoolbar.

+3
source

If you want to print / write all SQL queries from tests, try subclassing TestCase as follows:

 from django.conf import settings from django.template import Template, Context import sys from django.db import connection from django.test import TestCase class LoggingTestCase(TestCase): @staticmethod def setUpClass(): # The test runner sets DEBUG to False. Set to True to enable SQL logging. settings.DEBUG = True super(LoggingTestCase, LoggingTestCase).setUpClass() @staticmethod def tearDownClass(): super(LoggingTestCase, LoggingTestCase).tearDownClass() time = sum([float(q['time']) for q in connection.queries]) t = Template("{{count}} quer{{count|pluralize:\"y,ies\"}} in {{time}} seconds:\n\n{% for sql in sqllog %}[{{forloop.counter}}] {{sql.time}}s: {{sql.sql|safe}}{% if not forloop.last %}\n\n{% endif %}{% endfor %}") print >> sys.stderr, t.render(Context({'sqllog': connection.queries, 'count': len(connection.queries), 'time': time})) # Empty the query list between TestCases. connection.queries = [] 

Then use LoggingTestCase instead of TestCase as the base class in your tests. Remember to call it tearDownClass if you redefine it.

+17
source

You can also do the following to receive requests (and then, for example, print or evaluate it in your test).

Actually, you should not change django.conf.settings present, so I use override_settings .

 from django.db import connection, reset_queries from django.test import override_settings, TransactionTestCase class TransactionTests(TransactionTestCase): @override_settings(DEBUG=True) def test_sql(self): reset_queries() try: # Code that uses the ORM goes here except Exception as e: pass self.assertEqual(connection.queries, []) 

TestCase may also work, see Differences in this answer .

See the Django Documentation for details on SQL output.

+4
source

This is not a clean solution, but if you just want to debug without installing additional packages, you can look for the execute () method in django / db.

For Oracle , I think it is in:

django / db / backends / oracle / base.py and find:

 def execute 

For PostgreSQL, it is located in:

Django / db / backends / postgresql_psycopg2 / base.py

There is an execute () method in CursorWrapper.

Both catch IntegrityError and DatabaseError, you can add a print statement there. A.

For ppl who want to see all SQL queries, put a print statement right after the function call.

+2
source

You can change the console level to DEBUG in the settings. He worked on Django 1.9.

 LOGGING = { ... 'handlers': { 'console': { 'level': 'DEBUG', 'class': 'logging.StreamHandler', 'formatter': 'simple' }, } ... } 
0
source

Another option is to use connection.execute_wrapper() in your test as follows:

 def logger(execute, sql, params, many, context): print(sql, params) return execute(sql, params, many, context) class GizmoTest(TestCase): def test_with_sql_logging(self): with connection.execute_wrapper(logger): code_that_uses_database() 

Tested with Django 2.2.

0
source

All Articles