【问题标题】:Strange hex character behavior with mysqldumpmysqldump 奇怪的十六进制字符行为
【发布时间】:2014-02-03 07:08:05
【问题描述】:

我有一个(令人沮丧的)谜团需要帮助解决。我有一个 MySQL 表,其中有一列存储 URL,特别是 last.fm 上跟踪的 URL。我认为我确保将它们存储为转义的 html 格式(例如,“ünloco”变为“'%C3%BCnloco”),因为我使用的是拉丁排序规则(不是 utf-8),但是发生了一些奇怪的事情。

我用 mysqldump 备份了表,截断了表,然后尝试使用标准的“load data infile”语法重新导入相同的数据。

但它会在读取约 4000 万行的约 300k 行后停止(它不是行终止问题...已经检查过)。没有错误,没有警告……好像 MySQL 认为文件比实际要短。

在将文件读入 Python 后,发现它在包含十六进制字符的行上失败(例如 \xa0)。也就是说,它将读取所有行,直到它碰到那一行。我通过删除该行并重试来验证这是问题所在,然后它将数据加载到带有十六进制字符的 next 行,然后停止。

所以这些字符肯定是问题所在,但我不知道它们是如何出现在表格中的(拉丁排序规则不应该不允许吗?)。更重要的是,我现在如何将数据恢复到数据库中?

我是否必须手动编辑转储的文本文件并删除/编辑这些行,或者有没有办法让 MySQL 正确读取文件?在前一种情况下,我怎样才能有效地找到有问题的行(命令行或 Python 解决方案赞赏......有太多行需要手动检查)。


编辑以包含有问题的行的示例,我学到的第一个是:

for i,line in enumerate(open(filename)):
    if i==350616:
        break

print line 
350317  2       sevish  346067  \N      á       sevish/_/á

print repr(line)
'350317\t2\tsevish\t346067\t\\N\t\xa0\tsevish/_/\xa0\n'

【问题讨论】:

  • 另见*.com/questions/752998/… 并请追踪 \xa0 的来源或使用,因为它可能很重要。也许你正在存储特殊的引号之类的东西。
  • 在挖掘了一些旧的数据库备份之后,问题肯定是一些特殊字符以某种方式最终出现在数据库中(我仍然不知道如何!)。我可以修复它们,但仍然需要一种方法来识别哪些行包含此类字符...

标签: python mysql


【解决方案1】:

(我假设 \xa0 是文件中的单个字节,并且您在 Windows 上。)

以二进制模式打开。

file = open(fname, 'rb')

否则,它假定 ASCII 并且可以在非 ASCII 字符上中断(\x80 左右及以上)。

注意:您将从读取操作中获取字节数组,而不是字符串。您可能需要使用 str 转换输入,这可能仍会在非 ASCII 上中断。

在二进制模式下,您不应使用 next(将文件用作可迭代)、readlinereadlines,因为它们会查找 ASCII。请改用read

【讨论】:

  • 这实际上并没有帮助......像这样读取文件提供的结果与我对上述问题的编辑相同。
  • 您可能正在使用 readline,它不理解非 ASCII。
【解决方案2】:

好的,所以我终于找到了一种或多或少简单地找出哪些行有问题的方法:

for line in open(filename):
    try:
        line.decode('ascii')
    except:
        print line

基本上,我尝试在 ascii 中解码该行,如果这不起作用,我打印该行。这提取了相关行并允许我对其进行编辑,以便 MySQL 可以正确读取它们。

这当然没有解决如何这些值首先到达那里,但至少允许我解决问题。

【讨论】:

    最近更新 更多