我有一个 Postgres 8.4 环境,我们所有数据库的编码都设置为SQL_ASCII
- 我们终于迁移到 Postgres 9.2,我想将所有内容迁移到UTF8
编码。
不幸的是,这个数据库中的文本数据不干净——尝试将 pg_dump 恢复到 utf8 编码的数据库会引发有关无效字节序列的错误,即使我--encoding=UTF8
在运行 pg_dump 时指定(可能是因为 Postgres 不知道该怎么做他们并只是将它们原封不动地转储?)。
我们有很多数据(超过一百万行带有文本/字符串元素),手动审核所有这些数据将非常耗时(并且容易出错),所以如果可能的话,我希望将其自动化。
有没有一种简单的方法可以在数据库中找到不符合 utf8 的字符串/文本字段,以便我们修复它们?还是我坚持进行手动审核以解决这个问题?
我怀疑您的数据库内容可能在 iso8859 或 cp1252 中。如果它是 ascii,那么导入它就不会遇到问题。您可以通过使用 python 打开转储来确定编码。以下 python3 尝试编码,直到成功。它可用于确定文件编码。
Python 也可用于访问数据库和审计数据。如有必要,它还可用于在复制数据时将数据转码为 UTF-8。
损坏的文本编码转储很难处理。
通常的 - 并且公认的粗略 - 解决方案是
iconv
在 SQL 格式转储上运行,并使用-c
标志告诉它忽略在目标编码中无效的字符。这只有在原始数据库应该采用一种主要编码时才可行,并且由于未能实际执行和检查该编码而到处都有一些坏数据。
如果原始数据库采用混合/多种编码,则这种方法将不会真正起作用。您必须进行每个字段的字符集检测,使用诸如 PL/Python 或 PL/Perl 存储过程之类的东西对每个字段进行最佳猜测编码检测,将其转换为目标编码(比如 utf-8),
UPDATE
然后带有重新编码文本的字段。不用说这会很慢而且很笨重,但是如果每个字段都可以有不同的编码,那么就没有什么可做的了。这种方法不精确且容易出错。它仍然会给您留下错误编码的错误文本。但是,该文本之前也可能在应用程序中显示错位,因为它会以一种编码存储,然后在另一种编码中重新解释以进行显示。
您可以使用 uchardet 来确定编码:
https://code.google.com/p/uchardet/
然后使用 iconv,可能与 -c 一起使用,在编码之间进行转换:
http://www.documentroot.com/2013/12/utf8-encoding-and-postgres-dump.html