我在MySQL中保存Unicode字符时遇到问题。
Exception Type: UnicodeEncodeError
Exception Value:
'ascii' codec can't encode character u'xed' in position 39: ordinal not in range(128)
Exception Location: /home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/MySQLdb/connections.py in string_literal, line 204
Python Executable: /home/truhlik/.virtualenvs/reality/bin/python
Python Version: 2.7.11
MySQL库中出现错误:
def _get_string_literal():
def string_literal(obj, dummy=None):
# try:
return db.string_literal(obj) ...
# except UnicodeEncodeError:
# return db.string_literal(unicode(obj).encode("utf-8"))
return string_literal
变量:
obj = u'temp/files_widget/2016-05-31-15-00/1/Snxedmek obrazovky pou0159xedzenxfd 2016-05-23 10-34-59.png'
我认为问题与这个问题有关:python-使用Django 将Unicode字符存储到MySQL时出现问题
我的"obj"变量不是纯Unicode,但它是ImagePath类实例。
class ImagePaths(unicode):
item_class = ImagePath
问题是我不知道应该采用哪种方法来解决这个问题。
注:我的修复在上面的代码中有注释。但这并不是什么干净的解决方案。它是直接在MySQL库中编写的。
更新#1:
完整回溯:
/home/truhlik/Dropbox/web/reality/permissions/models.py in save
super(CustomModel, self).save(*args, **kwargs) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/models/base.py in save
force_update=force_update, update_fields=update_fields) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/models/base.py in save_base
updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/models/base.py in _save_table
forced_update) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/models/base.py in _do_update
return filtered._update(values) > 0 ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/models/query.py in _update
return query.get_compiler(self.db).execute_sql(CURSOR) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py in execute_sql
cursor = super(SQLUpdateCompiler, self).execute_sql(result_type) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/models/sql/compiler.py in execute_sql
cursor.execute(sql, params) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/backends/utils.py in execute
return super(CursorDebugWrapper, self).execute(sql, params) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/backends/utils.py in execute
return self.cursor.execute(sql, params) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/django/db/backends/mysql/base.py in execute
return self.cursor.execute(query, args) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/MySQLdb/cursors.py in execute
query = query % tuple([db.literal(item) for item in args]) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/MySQLdb/connections.py in literal
return self.escape(o, self.encoders) ...
/home/truhlik/.virtualenvs/reality/local/lib/python2.7/site-packages/MySQLdb/connections.py in string_literal
return db.string_literal(obj)
使用此连接设置:
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'reality_devel',
'USER': 'reality_devel',
'HOST': 'mail.it-poradce.cz',
'PORT': '3306',
'OPTIONS': {
'charset': 'utf8',
'use_unicode': True,
}
}
MySQL数据库配置COLLATION 'utf8_general_ci' DEFAULT CHARACTER SET 'utf8'
发现了几个直接向Django和MySQL报告的问题,这些问题可能与我的问题有关。http://bugs.mysql.com/bug.php?id=79993和https://code.djangoproject.com/ticket/22377但我不确定。
更新#2:
我正在尝试使用此字段保存图像的路径。
images = files_widget.ImagesField(_(u'Obrázky'), blank=True, null=True, help_text=HELP_TEXT_IMAGES)
字段是这样实现的:
class FilesField(models.TextField):
description = _("Files")
attr_class = controllers.FilePaths
def __init__(self, *args, **kwargs):
self.accept = kwargs.pop('accept', None)
super(FilesField, self).__init__(*args, **kwargs)
def contribute_to_class(self, cls, name):
super(FilesField, self).contribute_to_class(cls, name)
receiver(post_save, sender=cls)(manage_files_on_disk)
setattr(cls, self.name, controllers.FilesDescriptor(self))
def save_form_data(self, instance, data):
save_all_data(self, instance, data)
super(FilesField, self).save_form_data(instance, data)
def formfield(self, default_widget=None, **kwargs):
if not default_widget:
default_widget = FilesWidget(field=self, accept=self.accept)
defaults = formfield_defaults(self, default_widget, **kwargs)
return super(FilesField, self).formfield(**defaults)
class ImagesField(FilesField):
description = _("Images")
attr_class = controllers.ImagePaths
def formfield(self, default_widget=None, **kwargs):
if not default_widget:
default_widget = ImagesWidget(field=self, accept=self.accept)
defaults = formfield_defaults(self, default_widget, **kwargs)
return super(ImagesField, self).formfield(**defaults)
它正在使用这个应用程序:django文件小部件。。。因此,如果你需要查看更多代码,那么你可以在GitHub上查看。抱歉,无法发布完整的URL
试图找到我应该在哪里…
正确转换为unicode
但不要搞清楚。
更新#3:
添加结果:SHOW VARIABLES LIKE 'char%'
character_set_client - utf8mb4
character_set_connection - utf8mb4
character_set_database - utf8
character_set_filesystem - binary
character_set_results - utf8mb4
character_set_server - latin1
character_set_system - utf8
character_sets_dir - /usr/share/mysql/charsets/
看起来您正在向库代码发送一个unicode
对象,它希望在库代码中接收str
对象。您发布的代码没有太多上下文可供参考(尝试发布整个回溯),但通过修改MySQLdb库来处理异常不是正确的方法。您应该在调用库的客户端代码中处理它。在回溯中查找引发异常的行之前的点,然后将try: except:
块移动到那里。
造成这种情况的原因之一是您的Connection
对象是使用use_unicode = False
创建的。
编辑:下面的一些示例代码。由于您没有发布CustomClass
的代码,我编写了以下简单的类,它运行得很好。
在模型中.py:
from __future__ import unicode_literals
from django.db import models
# Create your models here.
class CustomClass(models.Model):
path = models.CharField(max_length=200)
我用你的OPTIONS
建立了我的数据库。然后从外壳进行测试:
>>> c = CustomClass()
>>> c.path = u'temp/files_widget/2016-05-31-15-00/1/Snxedmek obrazovky pou0159xedzenxfd 2016-05-23 10-34-59.png'
>>> c.save()
>>>
也许您在代码中的某个地方做了一些非标准的事情,这导致了UnicodeEncodeError
。可能在您的自定义save()
方法或之前的其他客户端代码中。也许您使用的是一个自定义Field
子类,它不能正确地转换为unicode。
十六进制ed
不是Unicode,也不是utf8。也许你在等í
?这就是latin1编码的ed
。
ed
是从哪里来的?要么将其更改为用utf8编码,要么声明您使用的是latin1,而不是utf8。
Python提示:http://mysql.rjweb.org/doc.php/charcoll#python
Django提示:http://mysql.rjweb.org/doc.php/charcoll#other_computer_languages