Одно из моих приложений django unit test выходит из строя с
DatabaseError: ORA-00942: table or view does not exist
Я бы хотел увидеть фактический SQL-запрос, вызвавший эту ошибку. Вы знаете, как достичь этого?
Одно из моих приложений django unit test выходит из строя с
DatabaseError: ORA-00942: table or view does not exist
Я бы хотел увидеть фактический SQL-запрос, вызвавший эту ошибку. Вы знаете, как достичь этого?
Лучшим решением, которое я нашел до сих пор, является команда dzhango управления debugsqlshell, предоставляемая django-debugtoolbar.
Если вы хотите печатать/записывать все 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 = []
Затем используйте LoggingTestCase
вместо TestCase
как базовый класс в ваших тестах. Не забывайте называть это tearDownClass
, если вы его переопределите.
Вы также можете сделать следующее, чтобы получить запросы (а затем, например, распечатать или оценить его в своем тесте).
На самом деле вы не должны изменять 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, [])
TestCase
также может подойти, см. Различия в этом ответе.
См. Документацию Django для деталей для вывода SQL.
Это не самое чистое решение, но если вы просто захотите отлаживать без установки дополнительных пакетов, вы можете искать метод execute() в django/db.
Для Oracle, я думаю, он находится в:
django/db/backends/oracle/base.py и найдите:
def execute
Для PostgreSQL он находится в:
Джанго/дб/бэкэнды/postgresql_psycopg2/base.py
В CursorWrapper существует метод execute().
Оба ловут IntegrityError и DatabaseError, вы можете добавить там инструкцию печати.
Для ppl, которые хотят видеть все SQL-запросы, поставьте инструкцию печати сразу после вызова функции.
Вы можете изменить уровень консоли до DEBUG в настройках. Он работал на Django 1.9.
LOGGING = {
...
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
}
...
}
Другой вариант - использовать connection.execute_wrapper()
в вашем тесте следующим образом:
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()
Протестировано с Django 2.2.