답변:
docs FAQ : " Django가 실행중인 원시 SQL 쿼리를 어떻게 확인할 수 있습니까? "를 참조하십시오.
django.db.connection.queries
SQL 쿼리 목록을 포함합니다.
from django.db import connection
print(connection.queries)
또한 쿼리 셋에는 실행할 쿼리가 포함 된 query
속성 이 있습니다.
print(MyModel.objects.filter(name="my name").query)
다음과 같은 이유로 쿼리 출력이 유효한 SQL이 아닙니다.
"Django는 실제로 매개 변수를 보간하지 않습니다. 쿼리와 매개 변수를 개별적으로 데이터베이스 어댑터로 보내 적절한 작업을 수행합니다."
장고 버그 보고서 # 17741에서 .
따라서 쿼리 출력을 데이터베이스로 직접 보내면 안됩니다.
str()
내부 __str__()
메소드 를 호출하는 지정된 내장 Pythonian 함수 를 사용하는 것이 좋습니다 . 예를 들어 str(MyModel.objects.filter(name="my name").query)
프로젝트의 IPython과 Django 셸을 사용하는 것이 좋습니다. 그런 다음 탭 완성은 객체 내부 검사를 제공합니다. Django는 독창적 인 이름 지정 체계로 유명하기 때문에이 방법은 매우 유용한 경향이 있습니다.
query
"Django는 실제로 매개 변수를 보간하지 않습니다. 쿼리와 매개 변수를 데이터베이스 어댑터에 별도로 전송하여 적절한 조작을 수행합니다." 라는 결과 는 유효한 SQL이 아닙니다. 출처 : code.djangoproject.com/ticket/17741
stable
, not을 사용 dev
하여 다음과 같이 Django의 현재 버전에 연결해야합니다. docs.djangoproject.com/en/stable/faq/models/…
장고 확장 에는 매개 변수 가있는 shell_plus 명령이 있습니다.print-sql
./manage.py shell_plus --print-sql
장고 셸에서 실행 된 모든 쿼리가 인쇄됩니다.
전의.:
User.objects.get(pk=1)
SELECT "auth_user"."id",
"auth_user"."password",
"auth_user"."last_login",
"auth_user"."is_superuser",
"auth_user"."username",
"auth_user"."first_name",
"auth_user"."last_name",
"auth_user"."email",
"auth_user"."is_staff",
"auth_user"."is_active",
"auth_user"."date_joined"
FROM "auth_user"
WHERE "auth_user"."id" = 1
Execution time: 0.002466s [Database: default]
<User: username>
debug_toolbar를 살펴보면 디버깅에 매우 유용합니다.
설명서 및 소스는 http://django-debug-toolbar.readthedocs.io/ 에서 볼 수 있습니다 .
q = Query.objects.values('val1','val2','val_etc')
print q.query
m = MyModel.objects.get(...)
뒤 m.query
m
더 이상 쿼리 셋이 아니기 때문 입니다. q = MyModel.objects.filter(...)
,을 q.query
차례로 사용합니다 m = q.get()
.
다른 방법으로는이 방법을 다루지 않으므로 다음을 수행하십시오.
가장 유용하고 간단하며 신뢰할 수있는 방법은 데이터베이스를 요청하는 것입니다. 예를 들어 Linux for Postgres에서 다음을 수행 할 수 있습니다.
sudo su postgres
tail -f /var/log/postgresql/postgresql-8.4-main.log
각 데이터베이스마다 절차가 약간 다릅니다. 데이터베이스 로그에는 원시 SQL뿐만 아니라 모든 연결 설정 또는 트랜잭션 오버 헤드 django가 시스템에 있습니다.
log_statement='all'
에 postgresql.conf
이 방법을 위해.
postgresql.conf
psql -U postgres -c 'SHOW config_file'
제공된 코드를 사용하여 수행 할 수 있지만 디버그 도구 모음 앱을 사용하는 것이 쿼리를 표시하는 훌륭한 도구라는 것을 알았습니다. 여기 에서 github 에서 다운로드 할 수 있습니다 .
이를 통해 주어진 페이지에서 실행 된 모든 쿼리를 쿼리 시간과 함께 표시 할 수 있습니다. 또한 빠른 검토를 위해 페이지의 쿼리 수와 총 시간을 합산합니다. Django ORM이 무대 뒤에서 무엇을하는지보고 싶을 때 훌륭한 도구입니다. 그것은 또한 당신이 원한다면 사용할 수있는 다른 좋은 기능이 많이 있습니다.
다른 옵션은 settings.py의 로깅 옵션을 참조하십시오.
http://dabapps.com/blog/logging-sql-queries-django-13/
debug_toolbar는 개발자 서버의 각 페이지로드 속도를 늦추므로 로깅 속도가 빠르지 않습니다. 출력은 콘솔이나 파일로 덤프 될 수 있으므로 UI가 좋지 않습니다. 그러나 SQL이 많은 뷰의 경우 각 페이지로드가 너무 느리기 때문에 debug_toolbar를 통해 SQL을 디버깅하고 최적화하는 데 시간이 오래 걸릴 수 있습니다.
settings.py 파일에 다음이 있는지 확인하십시오.
django.core.context_processors.debug
에 나열된 CONTEXT_PROCESSORS
DEBUG=True
IP
에서 INTERNAL_IPS
튜플그런 다음 sql_queries
변수에 액세스해야 합니다. 다음과 같이 각 페이지에 바닥 글을 추가합니다.
{%if sql_queries %}
<div class="footNav">
<h2>Queries</h2>
<p>
{{ sql_queries|length }} Quer{{ sql_queries|pluralize:"y,ies" }}, {{sql_time_sum}} Time
{% ifnotequal sql_queries|length 0 %}
(<span style="cursor: pointer;" onclick="var s=document.getElementById('debugQueryTable').style;s.disp\
lay=s.display=='none'?'':'none';this.innerHTML=this.innerHTML=='Show'?'Hide':'Show';">Show</span>)
{% endifnotequal %}
</p>
<table id="debugQueryTable" style="display: none;">
<col width="1"></col>
<col></col>
<col width="1"></col>
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">SQL</th>
<th scope="col">Time</th>
</tr>
</thead>
<tbody>
{% for query in sql_queries %}
<tr class="{% cycle odd,even %}">
<td>{{ forloop.counter }}</td>
<td>{{ query.sql|escape }}</td>
<td>{{ query.time }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endif %}
sql_time_sum
줄을 추가 하여 변수 를 얻었습니다.
context_extras['sql_time_sum'] = sum([float(q['time']) for q in connection.queries])
django_src / django / core / context_processors.py의 디버그 기능에.
이 목적을 위해 확장 프로그램을 개발 했으므로 뷰 기능에 데코레이터를 쉽게 배치하고 얼마나 많은 쿼리가 실행되는지 확인할 수 있습니다.
설치하기 위해서:
$ pip install django-print-sql
컨텍스트 관리자로 사용하려면
from django_print_sql import print_sql
# set `count_only` to `True` will print the number of executed SQL statements only
with print_sql(count_only=False):
# write the code you want to analyze in here,
# e.g. some complex foreign key lookup,
# or analyzing a DRF serializer's performance
for user in User.objects.all()[:10]:
user.groups.first()
데코레이터로 사용하려면 :
from django_print_sql import print_sql_decorator
@print_sql_decorator(count_only=False) # this works on class-based views as well
def get(request):
# your view code here
PostgreSQL을 사용하는 경우 이것이 효과가 있다고 생각합니다.
from django.db import connections
from app_name import models
from django.utils import timezone
# Generate a queryset, use your favorite filter, QS objects, and whatnot.
qs=models.ThisDataModel.objects.filter(user='bob',date__lte=timezone.now())
# Get a cursor tied to the default database
cursor=connections['default'].cursor()
# Get the query SQL and parameters to be passed into psycopg2, then pass
# those into mogrify to get the query that would have been sent to the backend
# and print it out. Note F-strings require python 3.6 or later.
print(f'{cursor.mogrify(*qs.query.sql_with_params())}')
다음은 https://code.djangoproject.com/ticket/17741을 기반으로 쿼리를 유효한 SQL로 반환합니다 .
def str_query(qs):
"""
qs.query returns something that isn't valid SQL, this returns the actual
valid SQL that's executed: https://code.djangoproject.com/ticket/17741
"""
cursor = connections[qs.db].cursor()
query, params = qs.query.sql_with_params()
cursor.execute('EXPLAIN ' + query, params)
res = str(cursor.db.ops.last_executed_query(cursor, query, params))
assert res.startswith('EXPLAIN ')
return res[len('EXPLAIN '):]
사용할 수있는 작은 스 니펫을 만들었습니다.
from django.conf import settings
from django.db import connection
def sql_echo(method, *args, **kwargs):
settings.DEBUG = True
result = method(*args, **kwargs)
for query in connection.queries:
print(query)
return result
# HOW TO USE EXAMPLE:
#
# result = sql_echo(my_method, 'whatever', show=True)
kwargs는 해당 함수를 호출하는 데 필요한 매개 변수 함수 (SQL 쿼리 포함)를 검사하고 인수합니다. 결과적으로 어떤 함수가 콘솔에서 SQL 쿼리를 반환하고 인쇄하는지 반환합니다.
이 기능을 내 프로젝트의 앱 중 하나에있는 util 파일에 넣었습니다.
import logging
import re
from django.db import connection
logger = logging.getLogger(__name__)
def sql_logger():
logger.debug('TOTAL QUERIES: ' + str(len(connection.queries)))
logger.debug('TOTAL TIME: ' + str(sum([float(q['time']) for q in connection.queries])))
logger.debug('INDIVIDUAL QUERIES:')
for i, query in enumerate(connection.queries):
sql = re.split(r'(SELECT|FROM|WHERE|GROUP BY|ORDER BY|INNER JOIN|LIMIT)', query['sql'])
if not sql[0]: sql = sql[1:]
sql = [(' ' if i % 2 else '') + x for i, x in enumerate(sql)]
logger.debug('\n### {} ({} seconds)\n\n{};\n'.format(i, query['time'], '\n'.join(sql)))
그런 다음 필요할 때 가져 와서 필요한 컨텍스트 (일반적으로보기)에서 호출합니다. 예 :
# ... other imports
from .utils import sql_logger
class IngredientListApiView(generics.ListAPIView):
# ... class variables and such
# Main function that gets called when view is accessed
def list(self, request, *args, **kwargs):
response = super(IngredientListApiView, self).list(request, *args, **kwargs)
# Call our function
sql_logger()
return response
템플릿 외부에서이 작업을 수행하는 것이 좋습니다. API 뷰 (일반적으로 Django Rest Framework)가있는 경우에도 적용 할 수 있기 때문입니다.
Django 2.2의 경우 :
를 사용할 때 대부분의 답변이 저에게 도움이되지 않았기 때문에 ./manage.py shell
. 마침내 나는 답을 찾았습니다. 이것이 누군가에게 도움이되기를 바랍니다.
모든 쿼리를 보려면
from django.db import connection
connection.queries
단일 쿼리에 대한 쿼리를 보려면
q=Query.objects.all()
q.query.__str__()
q.query
나를 위해 객체를 표시합니다. __str__()
(문자열 표현)을 사용하여 전체 쿼리를 표시했습니다.