Respostas:
Consulte a documentação da FAQ: " Como posso ver as consultas SQL brutas que o Django está executando? "
django.db.connection.queries
contém uma lista das consultas SQL:
from django.db import connection
print(connection.queries)
Os conjuntos de consultas também têm um query
atributo que contém a consulta a ser executada:
print(MyModel.objects.filter(name="my name").query)
Observe que a saída da consulta não é SQL válido, porque:
"O Django nunca interpola realmente os parâmetros: envia a consulta e os parâmetros separadamente para o adaptador de banco de dados, que executa as operações apropriadas."
Do relatório de bug do Django # 17741 .
Por isso, você não deve enviar a saída da consulta diretamente para um banco de dados.
str()
função Pythonian incorporada especificada , que chama o __str__()
método interno . Por exemplo, str(MyModel.objects.filter(name="my name").query)
eu também recomendaria o uso do IPython e do shell Django do seu projeto. A conclusão da guia fornece introspecção de objetos. Como o Django é conhecido por seus esquemas de nomeação assertivos, essa metodologia tende a ser muito útil.
query
não é SQL válido, porque "o Django nunca interpola realmente os parâmetros: envia a consulta e os parâmetros separadamente para o adaptador de banco de dados, que executa as operações apropriadas." Fonte: code.djangoproject.com/ticket/17741
stable
, não dev
, para link para a versão atual do Django, como este: docs.djangoproject.com/en/stable/faq/models/...
O Django-extensions possui um comando shell_plus com um parâmetroprint-sql
./manage.py shell_plus --print-sql
No django-shell, todas as consultas executadas serão impressas
Ex.:
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>
Dê uma olhada em debug_toolbar , é muito útil para depuração.
A documentação e a fonte estão disponíveis em http://django-debug-toolbar.readthedocs.io/ .
q = Query.objects.values('val1','val2','val_etc')
print q.query
m = MyModel.objects.get(...)
seguido porm.query
m
não é mais um conjunto de consultas. Use q = MyModel.objects.filter(...)
, então q.query
, então m = q.get()
.
Nenhuma outra resposta cobre esse método, portanto:
Acho, de longe, o método mais útil, simples e confiável é perguntar ao seu banco de dados. Por exemplo, no Linux para Postgres, você pode fazer:
sudo su postgres
tail -f /var/log/postgresql/postgresql-8.4-main.log
Cada banco de dados terá um procedimento ligeiramente diferente. Nos logs do banco de dados, você verá não apenas o SQL bruto, mas qualquer configuração de conexão ou sobrecarga de transação que o django esteja colocando no sistema.
log_statement='all'
em postgresql.conf
por este método.
postgresql.conf
executandopsql -U postgres -c 'SHOW config_file'
Embora você possa fazer isso com o código fornecido, acho que o uso do aplicativo da barra de ferramentas de depuração é uma ótima ferramenta para mostrar consultas. Você pode baixá-lo no github aqui .
Isso oferece a opção de mostrar todas as consultas executadas em uma determinada página, juntamente com o tempo necessário para a consulta. Também resume o número de consultas em uma página e o tempo total para uma revisão rápida. Esta é uma ótima ferramenta, quando você deseja ver o que o Django ORM faz nos bastidores. Ele também possui muitos outros recursos interessantes que você pode usar se quiser.
Outra opção, consulte as opções de log em settings.py descritas nesta postagem
http://dabapps.com/blog/logging-sql-queries-django-13/
debug_toolbar diminui a velocidade de cada carregamento de página no servidor de desenvolvimento, o registro não é mais rápido. As saídas podem ser despejadas no console ou arquivo, para que a interface do usuário não seja tão boa. Porém, para visualizações com muitos SQLs, pode demorar muito tempo para depurar e otimizar os SQLs através do debug_toolbar, pois o carregamento de cada página é muito lento.
Se você se certificar de que seu arquivo settings.py possui:
django.core.context_processors.debug
listados em CONTEXT_PROCESSORS
DEBUG=True
IP
na INTERNAL_IPS
tuplaEntão você deve ter acesso à sql_queries
variável. Anexo um rodapé a cada página que se parece com isso:
{%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 %}
Eu peguei a variável sql_time_sum
adicionando a linha
context_extras['sql_time_sum'] = sum([float(q['time']) for q in connection.queries])
para a função de depuração em django_src / django / core / context_processors.py.
Desenvolvi uma extensão para esse fim, para que você possa colocar facilmente um decorador na sua função de visualização e ver quantas consultas são executadas.
Para instalar:
$ pip install django-print-sql
Para usar como gerenciador de contexto:
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()
Para usar como decorador:
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
Acredito que isso funcione se você estiver usando o 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())}')
A seguir, a consulta retorna como SQL válido, com base em https://code.djangoproject.com/ticket/17741 :
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 '):]
Fiz um pequeno trecho que você pode usar:
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)
Ele assume como função de parâmetros (contém consultas sql) para inspecionar e args, kwargs necessários para chamar essa função. Como resultado, ele retorna qual função retorna e imprime consultas SQL em um console.
Coloquei essa função em um arquivo util em um dos aplicativos do meu projeto:
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)))
Então, quando necessário, basta importá-lo e chamá-lo de qualquer contexto (geralmente uma visualização) que seja necessário, por exemplo:
# ... 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
É bom fazer isso fora do modelo, porque, se você tiver visualizações de API (geralmente o Django Rest Framework), é aplicável também.
Para o Django 2.2:
Como a maioria das respostas não me ajudou muito ao usar ./manage.py shell
. Finalmente eu encontrei a resposta. Espero que isso ajude alguém.
Para visualizar todas as consultas:
from django.db import connection
connection.queries
Para visualizar a consulta para uma única consulta:
q=Query.objects.all()
q.query.__str__()
q.query
apenas exibindo o objeto para mim. O uso da __str__()
(representação de String) exibiu a consulta completa.
Exibir consultas usando django.db.connection.queries
from django.db import connection
print(connection.queries)
Acessar consulta SQL bruta no objeto QuerySet
qs = MyModel.objects.all()
print(qs.query)
Apenas para adicionar, no django, se você tiver uma consulta como:
MyModel.objects.all()
Faz:
MyModel.objects.all().query.sql_with_params()
para obter a string sql