django运行测试时如何查看sql查询?

mno*_*tka 10 sql oracle django unit-testing django-testing

我的一个django应用程序单元测试失败了

DatabaseError: ORA-00942: table or view does not exist
Run Code Online (Sandbox Code Playgroud)

我想看到导致此错误的实际SQL查询.你知道怎么做吗?

tuo*_*alo 17

如果要打印/记录测试中的所有 SQL查询,请尝试使用以下子TestCase类化:

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 = []
Run Code Online (Sandbox Code Playgroud)

然后在测试中使用LoggingTestCase而不是TestCase作为基类.tearDownClass如果你覆盖它,请记住调用它.


Duš*_*ďar 11

另一种选择是使用CaptureQueriesContext(用 测试pytest)。

from django.db import connection
from django.test.utils import CaptureQueriesContext


def test_foo():
    with CaptureQueriesContext(connection) as ctx:
        # code that runs SQL queries
        print(ctx.captured_queries)
Run Code Online (Sandbox Code Playgroud)

资料来源:

  • 这是最简单、最干净的答案,因为它可以让您捕获任意小代码部分的查询,如果您想要解决问题或优化查询,这就是您想要的。 (2认同)

Eer*_*ist 6

另一种选择是connection.execute_wrapper()在您的测试中使用,如下所示:

from django.db import connection

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()
Run Code Online (Sandbox Code Playgroud)

用 Django 2.2 测试。


yof*_*fee 5

您还可以执行以下操作来获取查询(例如,在测试中将其打印或评估)。

实际上,如今您不应该更改django.conf.settings,因此我使用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, [])
Run Code Online (Sandbox Code Playgroud)

TestCase可能也合适,请参见此答案中的区别。

有关SQL输出的详细信息,请参见Django文档


mno*_*tka 0

到目前为止我发现的最好的解决方案是 django-debugtoolbar 提供的 debugsqlshell 自定义 django 管理命令。

  • 您能否详细说明如何使用“debugsqlshell”命令来运行测试。django-debugtoolbar 的文档中没有对此进行解释。 (3认同)