Журнал запросов базы данных django
Я регистрирую свои запросы к базе данных в Django вместе с путевым именем и номером белья.
Прямо сейчас я получаю эти журналы:
07/Dec/2018 14:25:00 DEBUG django.db.backends utils **/Users/XXXXX/.idea/lib/python2.7/site-packages/django/db/backends/utils.py:89**
(0.340) SELECT "metadata"."metaname", "metadata"."description", "metadata"."attributes" FROM "metadata" WHERE "metadata"."metaname" = 'date_type'; args=('date_type',)
Для всех запросов я получаю одинаковый путь и номер строки. Есть ли способ, которым я могу получить номер строки из моего основного приложения, а не из утилиты.
Текущая реализация журнала:
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'color'
},
},
'loggers': {
'django.db.backends': {
'handlers': ['console'],
'level': 'DEBUG',
'propogate': True,
}
}
}
Использование Python 2.7 и Django 1.9
1 ответ
Я предполагаю, что вы пытаетесь определить, какие строки в вашем приложении отвечают за выполнение каких запросов.
Одним из способов достижения этого было бы создание пользовательского обработчика, который распечатывает текущий стек в точке, где Django регистрирует запрос. Это позволит вам увидеть, какая строка в вашем приложении выполняется.
Вы можете создать собственный обработчик, такой как:
import logging
import traceback
class StackInfoHandler(logging.StreamHandler):
trim = 5
def emit(self, record):
super(StackInfoHandler, self).emit(record)
stack = ''.join(
str(row) for row in traceback.format_stack()[:-self.trim]
)
self.stream.write(stack)
А затем в вашей конфигурации регистрации вы можете просто переключить класс обработчика, чтобы использовать StackInfoHandler
:
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'my.package.StackInfoHandler', # Reference the custom handler
'formatter': 'color'
},
},
Обратите внимание, что StackInfoHandler
удаляет 5 строк из стека, чтобы он не отображал кадры стека из самой структуры ведения журнала. Возможно, вам придется настроить это число (5 работает для меня на местном уровне).
Слегка оптимизированная версия от User @will-keeling
Конфигурация журнала для Django для номеров строк вывода для каждого запроса базы данных.
Примечание. Если вы хотите использовать его для тестов, вам необходимо установить DEBUG=True для тестов. Как установить DEBUG в значение True при запуске теста Django?
import logging
import traceback
from django.conf import settings
class StackInfoHandler(logging.StreamHandler):
trim = 5
def emit(self, record):
super(StackInfoHandler, self).emit(record)
trace = traceback.format_stack()
stack1 = [str(row) for row in trace]
stack2 = [s for s in stack1 if settings.BASE_DIR in s and 'format_stack' not in s]
stack3 = [s for s in stack2 if 'test' not in s]
if not stack3:
stack3 = stack2 # include test call
if stack3:
stack4 = ''.join(stack3[-self.trim:]) # take only last records
stack5 = f"Stack {self.terminator} {''.join(stack4)}"
self.stream.write(stack5)
self.stream.write(self.terminator)
self.flush()
Конфигурация ведения журнала (частичная)
LOGGING = {
'handlers': {
'db-console': {
'level': 'DEBUG',
'class': 'settings.local.StackInfoHandler', # Reference the custom handler
'formatter': 'simple',
},
'loggers': {
'django.db.backends': {
'handlers': ['db-console'],
'level': 'DEBUG',
'propagate': False
},
}
}
}
Это покажет вам только трассировку стека из вашей кодовой базы Django, как показано ниже.
[2020-05-25 17:49:17,977]: (0.000) INSERT INTO `contacts_contactscount` (`user_id`, `date`, `amount`) VALUES (338, '2020-05-25 17:49:17', 7); args=[338, '2020-05-25 17:49:17', 7]
Stack
File "<project-root>/api/views/contacts.py", line 164, in create
Contact.objects.filter(pk__in=to_delete).delete()
File "<project-root>/<folder>/contacts/models.py", line 54, in delete
create_deletion_log.delay(obj, deleted_timestamp)
File "<project-root>/<folder>/contacts/tasks.py", line 31, in create_deletion_log
contact.save()
File "<project-root>/<folder>/contacts/models.py", line 118, in save
Contact.objects.contacts_added_hook(self.user)
File "<project-root>/<folder>/contacts/models.py", line 67, in contacts_added_hook
current_total = user.profile.contacts_total
File "<project-root>/<folder>/profile/models.py", line 631, in contacts_total
ContactsCount.objects.create(user=self.user, amount=count)