【问题标题】:pysqlite2: ProgrammingError - You must not use 8-bit bytestringspysqlite2: ProgrammingError - 你不能使用 8 位字节串
【发布时间】:2011-02-19 18:05:18
【问题描述】:

我目前出于自己的目的将文件名保存在 sqlite 数据库中。每当我尝试插入具有特殊字符(如 é 等)的文件时,都会引发以下错误:

pysqlite2.dbapi2.ProgrammingError: You must not use 8-bit bytestrings unless you use a text_factory that can interpret 8-bit bytestrings (like text_factory = str). It is highly recommended that you instead just switch your application to Unicode strings.

当我通过使用诸如unicode(filename) 之类的 unicode 方法包装发送到 pysqlite 的值来“将我的应用程序切换到 Unicode 字符串”时,它会引发此错误:

UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 66: ordinal not in range(128)

我可以做些什么来摆脱这种情况吗?修改我的所有文件以符合要求不是一种选择。

更新 如果我通过filename.decode("utf-8") 解码文本,我仍然会收到上面的 ProgrammingError。

我的实际代码如下所示:

cursor.execute("select * from musiclibrary where absolutepath = ?;",
    [filename.decode("utf-8")])

我的代码应该是什么样的?

【问题讨论】:

  • 看起来这段代码,在你更新问题后,实际上不是产生错误的代码,对吧?
  • 对,后来在应用程序中是类似的代码。

标签: python sqlite pysqlite


【解决方案1】:

您需要指定filename 的编码以转换为Unicode,例如:filename.decode('utf-8')。仅使用unicode(...) 会选择控制台编码,这通常是不可靠的(通常是ascii)。

【讨论】:

  • 我试过这样做,但似乎我仍然收到上述错误。我用我现在正在做的事情更新了帖子,所以你可以看到我在做什么。谢谢!
  • 我的错,我后来在我的脚本中发生了一些更糟糕的转换,引发了同样的错误:)
【解决方案2】:

您应该将 SQL 语句的参数作为 Unicode 传递。

现在,这一切都取决于如何您获得文件名列表。也许您正在使用os.listdiros.walk 读取文件系统?如果是这种情况,有一种方法可以直接将文件名作为 Unicode,只需将 Unicode 参数传递给以下任一函数:
例子:

  • os.listdir(u'.')
  • os.walk(u'.')

当然,您可以将u'.' 目录替换为您正在阅读其内容的实际目录。只要确保它是一个 Unicode 字符串。

【讨论】:

    【解决方案3】:

    您是否尝试过直接传递 unicode 字符串:

    cursor.execute("select * from musiclibrary where absolutepath = ?;",(u'namé',))
    

    您需要在脚本开头添加文件编码:

    # coding: utf-8
    

    【讨论】:

    • 如果我尝试这样做,它似乎可以工作。我正在迭代大约 3000 个文件,它在文件名上失败,例如: 02 - Neighborhood #2 (Laïka).mp3 。有没有我在某处遗漏的转换技术?
    【解决方案4】:

    你已经想通了,但是:

    我认为您实际上无法从 cursor.execute("select * from musiclibrary where absolutepath = ?;", [filename.decode("utf-8")]) 中获得 ProgrammingError 异常,作为当前的问题州。

    utf-8 解码会爆炸,或者 cursor.execute 调用会对结果感到满意。

    【讨论】:

      【解决方案5】:

      试着改成这样:

      cursor.execute("select * from musiclibrary where absolutepath = ?;",
          [unicode(filename,'utf8')])
      

      在您的文件名来源中未使用utf8 编码,将utf8 更改为您的编码。

      【讨论】:

        猜你喜欢
        • 2014-07-15
        • 2011-03-26
        • 1970-01-01
        • 1970-01-01
        • 2011-08-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多