首页 > 解决方案 > 使用 BinaryField 中的 unicode 记录 sql 时出现 Django UnicodeEncodeError

问题描述

Django 1.11、Python 3.5、Windows 操作系统

我有一个带有 BinaryField 的 Django 模型。当我将模型的实例保存到数据库时,Django 会打印出如下错误消息:

UnicodeEncodeError: 'charmap' codec can't encode character '\ufffd' in position 216: character maps to <undefined>

回溯的最后一行表明错误发生在django.db.backends.utils.py——我在有问题的行中添加了注释:

class CursorDebugWrapper(CursorWrapper):

    # XXX callproc isn't instrumented at this time.

    def execute(self, sql, params=None):
        start = time()
        try:
            return super(CursorDebugWrapper, self).execute(sql, params)
        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,
            })
            ##### Error is reported from the logger.debug statement
            logger.debug(
                '(%.3f) %s; args=%s', duration, sql, params,
                extra={'duration': duration, 'sql': sql, 'params': params}
            )

所以我认为发生的事情是,当 Django 尝试打印 SQL 插入语句时,它会遇到不可打印的 Unicode 字符并引发错误。我不想在开发时禁用 Django 调试日志记录(当然,它在生产中被禁用)。有什么办法可以解决这个问题?

标签: pythondjangounicode

解决方案


将日志处理程序的编码设置为 utf-8 似乎有效。如果有更好的方法请指教。

LOGGING = {
    # other config omitted
    'handlers': {
        'django-debug': {
            'level': 'DEBUG',
            'class':'logging.FileHandler',
            'filename': os.path.join(LOCAL_LOGGING_PATH,'django-debug.log'),
            'formatter': 'standard',
            'encoding':'utf8', # this fixes UnicodeEncodeError
        }
    }
}

我尝试过的东西不起作用。这些仍然会产生 UnicodeEncodeError:

  • from __future__ import unicode_literals在 settings.py 顶部添加

  • 按照python 3 logging cookbook的建议,将字节顺序标记 (BOM) 字符 \ufeff 添加到格式化程序

  • 在日志格式化程序中使用 %r 而不是 %s

  • 在格式化程序上使用 python unicode 字符串'format': u'%(asctime)-s %(levelname)s [%(name)s]: %(message)s',,然后logging._defaultFormatter = logging.Formatter(u"%(message)s")按照此线程中的建议使用


推荐阅读