【问题标题】:Django UnicodeEncodeError when logging sql with unicode from BinaryField使用 BinaryField 中的 unicode 记录 sql 时出现 Django UnicodeEncodeError
【发布时间】:2019-05-31 06:20:20
【问题描述】:

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>

traceback 的最后一行表明错误发生在 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 调试日志记录(当然,它在生产中被禁用)。有什么办法可以解决这个问题?

【问题讨论】:

  • 我将 django 记录器的处理程序设置为 INFO 并防止错误。但后来我看不到调试级别的日志。
  • 您是否尝试过使用'%r' 而不是'%s' 来处理可能有问题的项目?

标签: python django unicode


【解决方案1】:

将日志处理程序的编码设置为 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:

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

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-06
    • 1970-01-01
    • 2011-01-07
    • 1970-01-01
    相关资源
    最近更新 更多