对整个项目应用 django.db.backends 修改

Applying django.db.backends modifications to entire project

所以我需要实现自己的 CursorWrappedDebug 来记录错误查询(在文件 django.db.backends.utils.py 中)。 我完成了:

logger = logging.getLogger('django.db.backends')

class CustomCursorDebugWrapper(CursorWrapper):
    def execute(self, sql, params=None):
        start = time()
        try:
            return super(CustomCursorDebugWrapper, self).execute(sql, params)

        except Error as e:
            exception=e

        finally:
            stop = time()
            duration = stop - start
            sql = self.db.ops.last_executed_query(self.cursor, sql, params)
            self.db.queries_log.append({
                'sql': sql,
                'time': "%.3f" % duration,
            })
            if 'exception' in locals():
                logger.error('(%.3f) %s; args=%s' % (duration, sql, params),extra={'duration': duration, 'sql': sql, 'params': params})
                raise exception
            else:
                logger.debug('(%.3f) %s; args=%s' % (duration, sql, params),extra={'duration': duration, 'sql': sql, 'params': params})


utils.CursorDebugWrapper = CustomCursorDebugWrapper

现在我需要将这些更改应用于整个项目(所有模块等)而不是当前文件。我是否应该制作自定义数据库后端,如果是,那么如何实现自定义数据库后端。

已编辑 找到解决方案(参见 link)https://docs.djangoproject.com/en/3.0/ref/databases/#subclassing-the-built-in-database-backends

找到解决方案(参见 link)https://docs.djangoproject.com/en/3.0/ref/databases/#subclassing-the-built-in-database-backends

我的自定义数据库目录:

mydbengine/
        __init__.py
        base.py

文件base.py:

from django.db.backends.postgresql_psycopg2 import base
from django.db.backends.utils import CursorWrapper
from django.db.utils import Error
from time import time
import logging

logger = logging.getLogger('django.db.backends')

class CustomCursorDebugWrapper(CursorWrapper):
    def execute(self, sql, params=None):
        start = time()
        try:
            return super(CustomCursorDebugWrapper, self).execute(sql, params)

        except Error as e:
            exception=e

        finally:
            stop = time()
            duration = stop - start
            sql = self.db.ops.last_executed_query(self.cursor, sql, params)
            self.db.queries_log.append({
                'sql': sql,
                'time': "%.3f" % duration,
            })
            if 'exception' in locals():
                logger.error('(%.3f) %s; args=%s' % (duration, sql, params),extra={'duration': duration, 'sql': sql, 'params': params})
                raise exception
            else:
                logger.debug('(%.3f) %s; args=%s' % (duration, sql, params),extra={'duration': duration, 'sql': sql, 'params': params})


    def executemany(self, sql, param_list):
        start = time()
        try:
            return super(CustomCursorDebugWrapper, self).executemany(sql, param_list)

        except Error as e:
            exception=e

        finally:
            stop = time()
            duration = stop - start
            try:
                times = len(param_list)
            except TypeError:           # param_list could be an iterator
                times = '?'
            self.db.queries_log.append({
                'sql': '%s times: %s' % (times, sql),
                'time': "%.3f" % duration,
            })
            if 'exception' in locals():
                logger.error('(%.3f) %s; args=%s' % (duration, sql, param_list),extra={'duration': duration, 'sql': sql, 'params': param_list})
                raise exception
            else:
                logger.debug('(%.3f) %s; args=%s' % (duration, sql, param_list),extra={'duration': duration, 'sql': sql, 'params': param_list})


class DatabaseWrapper(base.DatabaseWrapper):
    def make_debug_cursor(self, cursor):
        """
        Creates a cursor that logs all queries in self.queries_log.
        """
        return CustomCursorDebugWrapper(cursor, self)

现在我覆盖了 class CursorDebugWrapper 以记录错误级别的查询。 (仅 postgresql)

文件settings.py:

...

DATABASES = {
    'default': {
        'ENGINE': 'database',          
        'NAME': 'name',
        'USER': 'user',
        'PASSWORD': 'password',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

...

应用于项目