【发布时间】:2013-12-02 13:00:14
【问题描述】:
在从数据库中收集数据(使用 Python 和 SQLAlchemy)时,我们最近开始收到'utf8' codec can't decode bytes in position 30-31: unexpected end of data。我们已将错误定位到一些特殊的日文字符。
所有表都有CHARSET=utf8,这些是我运行show variables;时我们在服务器上的设置
| character_set_client | latin1
| character_set_connection | latin1
| character_set_database | latin1
| character_set_filesystem | binary
| character_set_results | latin1
| character_set_server | latin1
| character_set_system | utf8
| character_sets_dir | /usr/share/mysql/charsets/
| collation_connection | latin1_swedish_ci
| collation_database | latin1_swedish_ci
| collation_server | latin1_swedish_ci
如果我们不想将环境迁移到 utf8 - 建议使用哪些设置以及我们应该如何导出和导入当前数据以使其与新设置一起使用?
我已经阅读了一些关于将数据导出为 latin1 的帖子,方法是将 --default-character-set=latin1 添加到 mysqldump 命令,然后将其导入具有新设置的数据库,但由于我们的原始表已经在 utf8 中,因此不会工作。
阅读此帖后尝试设置连接:SQLAlchemy and UnicodeDecodeError
这解决了应用程序崩溃的问题,但所有旧数据都损坏了。
【问题讨论】:
-
你实际上有 latin1 数据。您需要获取它,将其编码为 UTF-8,然后重新导入到 UTF-8 归类表。我认为您不能简单地更改数据库和表的编码。确保也将连接设置为 UTF-8,在配置中或使用
SET NAMES。你做一个备份,然后尝试转换? -
尝试设置连接,它解决了崩溃的应用程序但损坏了旧数据。我已经更新了问题。
-
那么如果表有utf8编码并且连接是latin1,那么实际数据还是存储为latin1? @DanFromGermany
-
混合编码通常是个坏主意。这就像比较 EXE 和 PDF 文件 - 你不能。它们有不同的字节,不同的字符有不同的字节长度,不同的标头(如 BOM)。当您有一个 UTF-8 表并使用 latin1 连接使用 PHP 获取数据时,您将在 latin1 变量中获取 utf-8 数据,数据将被损坏。
-
您可能还会遇到双重编码。在这种情况下,最适合您的资源是性能博客,作者是 MariaDB、Percona、InnoDB 核心开发人员:mysqlperformanceblog.com/2013/10/16/…
标签: mysql utf-8 character-encoding mysqldump latin1