Como visualizar a consulta SQL correspondente ao conjunto de consultas do Django ORM?

164

Existe uma maneira de imprimir a consulta que o Django ORM está gerando?

Digamos que eu execute a seguinte instrução: Model.objects.filter(name='test')

Como faço para ver a consulta SQL gerada?

Jarvis
fonte

Respostas:

178

Cada objeto QuerySet possui um queryatributo que você pode registrar ou imprimir no stdout para fins de depuração.

qs = Model.objects.filter(name='test')
print qs.query

Editar

Também usei tags de modelo personalizadas (conforme descrito neste snippet ) para injetar as consultas no escopo de uma única solicitação como comentários em HTML.

Joe Holloway
fonte
6
e as consultas para .save ()?
DataGreed
@DataGreed Boa pergunta, pode valer a pena perguntar em um novo tópico para que você obtenha mais respostas.
Joe Holloway
4
Funciona com, por exemplo, prefetch_relatedmostrar 2 consultas? Eu vejo apenas 1.
usuário
não funciona. eu vejo<django.db.models.sql.query.Query object
dopatraman
Tente imprimir (str (qs.query)). Eu acho que eles mudaram um pouco os internos em 10 anos
Joe Holloway
114

Você também pode usar o log python para registrar todas as consultas geradas pelo Django. Basta adicionar isso ao seu arquivo de configurações.

LOGGING = {
    'disable_existing_loggers': False,
    'version': 1,
    'handlers': {
        'console': {
            # logging handler that outputs log messages to terminal
            'class': 'logging.StreamHandler',
            'level': 'DEBUG', # message level to be written to console
        },
    },
    'loggers': {
        '': {
            # this sets root level logger to log debug and higher level
            # logs to console. All other loggers inherit settings from
            # root level logger.
            'handlers': ['console'],
            'level': 'DEBUG',
            'propagate': False, # this tells logger to send logging message
                                # to its parent (will send if set to True)
        },
        'django.db': {
            # django also has database level logging
        },
    },
}

Outro método, caso o aplicativo esteja gerando saída html - a barra de ferramentas de depuração do django pode ser usada.

aisbaa
fonte
3
Se alguém gostaria de ter resumo com sumup do número de consultas executadas assim o tempo total demorou: dabapps.com/blog/logging-sql-queries-django-13
andilabs
9
Não funcionou para mim, eu tive que adicionar 'level': 'DEBUG'abaixo 'django.db'.
Rvernica
108

Você pode colar este código no seu shell, que exibirá todas as consultas SQL:

# To get all sql queries sent by Django from py shell
import logging
l = logging.getLogger('django.db.backends')
l.setLevel(logging.DEBUG)
l.addHandler(logging.StreamHandler())
Pramod
fonte
72

Enquanto DEBUGestiver ligado:

from django.db import connection
print(connection.queries)

Para uma consulta individual, você pode:

print(Model.objects.filter(name='test').query)
Daniel Roseman
fonte
22
Nota para os leitores: queryretorna o Queryobjeto desde o Djagno 1.2, que não possui as_sqlatributo.
Davor Lucic
30

Talvez você deva dar uma olhada no django-debug-toolbaraplicativo, ele registrará todas as consultas para você, exibirá informações de perfil para elas e muito mais.

Mikhail Korobov
fonte
3
Isso é muito útil, mas funciona apenas na GUI e, às vezes, você deseja ver os logs de consulta diretamente no ORM. por exemplo, você tem uma API, sem GUI!
wim
3

Uma solução robusta seria fazer o servidor de banco de dados registrar em um arquivo e, em seguida,

tail -f /path/to/the/log/file.log
Alan
fonte
2

Se você estiver usando o roteamento de banco de dados, provavelmente terá mais de uma conexão com o banco de dados. Um código como esse permite ver as conexões em uma sessão. Você pode redefinir as estatísticas da mesma maneira que em uma única conexão:reset_queries()

from django.db import connections,connection,reset_queries
...
reset_queries()  # resets data collection, call whenever it makes sense

...

def query_all():
    for c in connections.all():
        print(f"Queries per connection: Database: {c.settings_dict['NAME']} {c.queries}")

# and if you just want to count the number of queries
def query_count_all()->int:
    return sum(len(c.queries) for c in connections.all() )
Tim Richardson
fonte
1

Você pode usar um debango_toolbar do Django para visualizar a consulta SQL. Guia passo a passo para o uso de debug_toolbar:

Instale o Debug_toolbar

pip install django-debug-toolbar

Edite o arquivo settings.py e adicione debug_toolbar aos aplicativos instalados, isso deve ser adicionado abaixo a 'django.contrib.staticfiles'. Adicione também debug_toolbar ao Middleware.

Settings.py =>

INSTALLED_APPS= [ 'debug_toolbar'] 

MIDDLEWARE = ['debug_toolbar.middleware.DebugToolbarMiddleware']

crie uma nova lista denominada INTERNAL_IPS no arquivo settings.py

Settings.py => crie uma nova lista no final do arquivo settings.py e adicione a lista abaixo:

INTERNAL_IPS= [127.0.0.1']

Isso permitirá que a depuração seja executada apenas no servidor de desenvolvimento interno

Edite o arquivo urls.py de #Project e adicione o código abaixo:

if settings.DEBUG:
    import debug_toolbar
    urlpatterns = [
    url(r'^__debug__/', include(debug_toolbar.urls))       
    ] + urlpatterns

aplicar migrar e executar o servidor novamente

Você verá um complemento na sua página da Web em 127.0.0.1 e, se clicar na caixa de seleção Consulta SQL, poderá ver também o tempo de execução da consulta.

Devesh G
fonte