django 테스트를 실행할 때 sql 쿼리를 보는 방법은 무엇입니까?
django 애플리케이션 유닛 테스트 중 하나가 실패함
DatabaseError: ORA-00942: table or view does not exist
이 오류의 원인이 된 실제 SQL 쿼리를 보고 싶습니다.당신은 그것을 달성하는 방법을 알고 있습니까?
다른 옵션은 다음과 같습니다.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)
출처:
- https://blog.ploetzli.ch/2019/showing-sql-queries-with-pytest-and-django/
- 장고가 실행된 각 SQL 쿼리를 인쇄하도록 강제하는 방법
테스트에서 모든 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만약 당신이 그것을 무시한다면요.
또한 다음을 수행하여 쿼리를 가져올 수 있습니다(예를 들어, 인쇄하거나 테스트에서 평가).
사실 요즘은 당신이 변하면 안되기 때문에 제가 사용합니다.
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또한 적합할 수도 있습니다. 이 답변의 차이점을 참조하십시오.
SQL 출력에 대한 자세한 내용은 Django 설명서를 참조하십시오.
다른 옵션은 다음과 같이 테스트에 사용하는 것입니다.
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()
Django 2.2로 테스트했습니다.
가장 깨끗한 솔루션은 아니지만 추가 패키지를 설치하지 않고 빠르게 디버깅하고 싶다면 django/db에서 execute() 메서드를 찾을 수 있습니다.
Oracle의 경우 다음과 같은 이점이 있습니다.
django/db/backends/backends/base.py 에서 다음을 찾습니다.
def execute
Postgre용SQL 위치:
django/db/backends/postgresql_psycopg2/base.파이의
CursorWrapper에는 execute() 메서드가 있습니다.
둘 다 IntegrityError와 DatabaseError를 잡습니다. 여기에 인쇄문을 추가할 수 있습니다.
모든 sql 쿼리를 보고 싶은 ppl의 경우 함수 호출 바로 뒤에 print 문을 놓으십시오.
의 경우에는pytest그리고.pytest-django그냥 그것을 위한 고정 장치를 만듭니다.
@pytest.fixture
def debug_queries(db):
""" Because pytest run tests with DEBUG=False
the regular query logging will not work, use this fixture instead
"""
from django.db import connection
from django.test.utils import CaptureQueriesContext
with CaptureQueriesContext(connection):
yield connection
그렇다면 당신의 테스트에서.
@pytest.mark.django_db
def test__queries(debug_queries):
# run your queries here
물론 로깅 구성은 다음과 같은 쿼리 로깅을 활성화해야 합니다.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'standard': {
'format': '%(asctime)s - %(levelname)s - %(name)s - %(message)s',
},
},
'handlers': {
'default': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'standard',
'stream': 'ext://sys.stdout',
},
},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['default'],
'propagate': False,
},
}
}
지금까지 찾은 가장 좋은 해결책은 django-debug toolbar에서 제공하는 debugsqlshell custom django management 명령입니다.
설정에서 콘솔 수준을 DEBUG로 변경할 수 있습니다.장고 1.9에서 작동했습니다.
LOGGING = {
...
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
}
...
}
이것이 저에게 효과적인 솔루션이었습니다(Django 3.1).
from django.test import TestCase
class TestSomething(TestCase):
@override_settings(DEBUG=True)
def test_something(self):
pass
def tearDown(self):
from django.db import connection
for query in connection.queries:
print(f"✅ {query['sql']}\n")
여기에 있는 모든 옵션은 너무 복잡했습니다. 그리고 너무 많은 것들이 잘못될 수 있습니다.작동합니다.django>=1.11+<=4.x[그것을 위에 올려놓습니다.mainbranch] (미래에 그들이 그것을 깰 때까지...)
무시함으로써 작동합니다.settings.DEBUG예요.CursorDebugWrapper항상 사용되므로 실행된 SQL을 기록할 수 있습니다.
import inspect
from collections import deque
from contextlib import contextmanager
from unittest import mock
from django.db import connections
from django.db.backends import utils
@contextmanager
def print_queries(using="default"):
"""
[debug] Prints out all the queries in real time
To avoid messing with django's logging and get the SQL working inside
tests where `DEBUG` can be set to `False`, this bypasses all that and
goes straight for the kill.
Example:
class TestSomething(TestCase):
def test_something(self):
with print_queries():
Model.objects.create(a=1, b=2)
def test_something():
with print_queries():
Model.objects.create(a=1, b=2)
"""
def fake_maker(self, cursor):
"""
Normally `make_cursor` uses `CursorWrapper` which does NOT debug.
"""
return utils.CursorDebugWrapper(cursor, self)
class Snitch(deque):
"""
Modified version of `deque` that `print()`s out all the items inserted to it.
"""
def append(self, item):
current_frame = inspect.currentframe().f_back
while True:
info = inspect.getframeinfo(current_frame)
if "/django/" in info.filename:
current_frame = current_frame.f_back
continue
break
print("*", item["sql"], item["time"], f"{info.filename}:{info.lineno}")
return super().append(item)
connection_ = connections[using]
mock_maker = mock.patch("django.db.backends.base.base.BaseDatabaseWrapper.make_cursor", fake_maker)
mock_deque = mock.patch.object(connection_, "queries_log", Snitch(maxlen=connection_.queries_log.maxlen))
with mock_maker, mock_deque:
yield
다음과 같이 사용합니다.
def test_whatever():
...
with print_queries():
Model.objects.create(a=1, b=2) # any query here
...
출력은 다음과 같습니다.
* SELECT .. FROM "table" WHERE ... 0.001 /full/path/file.py:136
* SELECT .. FROM "table" WHERE ... 0.001 /full/path/file.py:245
코드에서 쿼리가 수행되는 위치를 알려줍니다.
언급URL : https://stackoverflow.com/questions/13162771/django-how-to-see-sql-query-when-running-tests
'programing' 카테고리의 다른 글
| VueJS - 저장된 데이터의 반응성 제한 (0) | 2023.06.13 |
|---|---|
| 수신기를 사용하여 데이터베이스의 데이터 변경 탐지 (0) | 2023.06.13 |
| AuthStateChanged에서 Firebase 수신 중지 (0) | 2023.06.13 |
| 디렉토리에 대한 cd-ing 없이 명령줄에서 Python 스크립트를 사용하려면 어떻게 해야 합니까?PYONPATH인가요? (0) | 2023.06.13 |
| 파이썬에서 줄임표 슬라이싱 구문을 어떻게 사용합니까? (0) | 2023.06.13 |