logar todas as consultas sql

99

Como posso registrar todas as consultas SQL que meu aplicativo django realizou?

Quero registrar tudo, incluindo SQLs do site de administração. Eu vi esta pergunta e uma resposta de FAQ, mas ainda não consigo descobrir onde devo colocar

from django.db import connection
connection.queries

registrar tudo em um arquivo?

Portanto, minha pergunta é - o que devo fazer para ter um arquivo (digamos all-sql.log) onde todas as instruções SQL são registradas?

Oleg Pavliv
fonte
stackoverflow.com/questions/1074212/…
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Respostas:

19

Verifique https://github.com/django-debug-toolbar/django-debug-toolbar

Ele permitirá que você veja todas as consultas geradas por uma determinada página. Bem como rastreamentos de pilha de onde ocorrem, etc.

EDITAR: para registrar todas as consultas SQL em um arquivo, etc, você vai querer criar algum middleware. Middleware é executado em cada solicitação. Existem vários snippets Django por aí para esse tipo de coisa:

Eles estão preocupados com a impressão no terminal, mas não seria difícil adaptá-los para usar a biblioteca de registro do python.

John Montgomery
fonte
180

Mesclar o seguinte snippet com o LOGGINGcampo em settings.py:

LOGGING = {
    'version': 1,
    'filters': {
        'require_debug_true': {
            '()': 'django.utils.log.RequireDebugTrue',
        }
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'filters': ['require_debug_true'],
            'class': 'logging.StreamHandler',
        }
    },
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
            'handlers': ['console'],
        }
    }
}

Ajustado de @ acardenas89 resposta

Gian Marco
fonte
3
pode ser necessário adicionar o seguinte à handlersseção caso obtenha Não foi possível adicionar o manipulador 'console': erro 'console' : 'console':{ 'level':'DEBUG', 'class':'logging.StreamHandler', 'formatter': 'verbose', 'stream': sys.stderr, },
Don Grem
1
Eu também precisava 'version': 1,no LOGGINGdict.
Dan
14
Observe que DEBUG deve ser TRUE para que os logs sejam realmente registrados. Independentemente das configurações de registro.
Janusz Skonieczny
3
Ah, e mais uma coisa no django corredor de teste ignora as configurações e substituições DEBUGpara False, assim, no teste que você deve@override_settings(DEBUG=True)
Janusz Skonieczny
7
Eu também adicionaria 'propagate': Falsedepois da 'handlers': ['console'],linha, caso você tenha um logger de root habilitado e não saiba porque ele imprime duas vezes. Demorei um pouco para perceber.
Andrei-Niculae Petre
45

Adicione as seguintes declarações em negrito em settings.py


se DEBUG:
    registro de importação
    l = logging.getLogger ('django.db.backends')
    l.setLevel (logging.DEBUG)
    l.addHandler (logging.StreamHandler ())


LOGGING = {
    'versão 1,
    'disable_existing_loggers': False,
    'filtros': {
        'require_debug_false': {
            '()': 'django.utils.log.RequireDebugFalse'
        }
    },
    'manipuladores': {
        'mail_admins': {
            'nível': 'ERROR',
            'filtros': ['require_debug_false'],
            'class': 'django.utils.log.AdminEmailHandler'
        }, 'console': {
            'nível': 'DEBUG',
            'classe': 'logging.StreamHandler',
        } ,
    },
    'loggers': {
        'django.request': {
            'handlers': ['mail_admins'],
            'nível': 'ERROR',
            'propagate': True,
        }, 'django.db.backends.sqlite3': {
            'nível': 'DEBUG',
            'handlers': ['console'],
        } ,
    }
}
  

Recurso / Crédito

cevaris
fonte
9
Você não precisa da ifdeclaração na parte superior e das LOGGINGalterações. A ifinstrução é para se você deseja adicionar o registro enquanto, por exemplo, no shell, para ativá-lo imediatamente - tudo que você precisa em settings.py são as LOGGINGmudanças - e você pode muito bem querer django.db.backends, não o específico sqlite3.
M Somerville
Não vejo nenhuma consulta no console executando o django 1.9. DEBUG = True.
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
1
@CiroSantilli 巴拿馬 文件 六四 事件 法轮功 Este é um comentário muito antigo, muito possivelmente o Django 1.9 não suporta esta solução da mesma forma.
cevaris
No Django 1.9, a DEBUGconfiguração é forçada a ser False durante a execução de testes. Uma solução alternativa é reativá-lo no teste
Diversos
7

Para registrar consultas SQL durante o teste, você precisa de duas coisas:

  1. django.db.backends logger habilitado e
  2. @override_settings(DEBUG=True) decorador.

O executor de teste definirá DEBUG = False por padrão, ignorando o que você pode ter definido em DJANGO_SETTINGS_MODULE.

As configurações mínimas:

# https://docs.djangoproject.com/en/dev/ref/settings/#logging
LOGGING = {
    'version': 1,
    'handlers': {
        'console': {
            'class': 'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'level': 'DEBUG',
        },
    },
    'root': {
        'handlers': ['console'],
    }
}

O exemplo de caso de teste:

from django.contrib.auth.models import User
from django.test import TestCase, override_settings


class UserTests(TestCase):

    # To log queries in tests you need to manually override DEBUG setting
    # because testing sets DEBUG=False by default

    @override_settings(DEBUG=True)
    def test_create_user(self):
        User.objects.create()
Janusz Skonieczny
fonte
2

Você só precisa:

@override_settings(DEBUG=True)

se você já tem instruções de depuração SQL sendo impressas em runserver .

Adicione o decorador ao seu class TestA(TestCase)ou test_function:

@override_settings(DEBUG=True)
class TestA(TestCase):
...

    @override_settings(DEBUG=True)
    def test_function(self):
    ...

Créditos à resposta de @Janusz Skonieczny!

vedante
fonte
0

Você precisa colocar isso em um pacote de middleware. O middleware fica entre o núcleo do servidor web / django e todas as suas visualizações. Ele pode fazer o pré-processamento antes da solicitação e o pós-processamento após a conclusão da solicitação. Por exemplo, salve as consultas em um arquivo.

vdboor
fonte