pysqlite2:ProgrammingError - 您不能使用8位字节串

13

我目前正在为自己的目的将文件名存储在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方法包装发送给pysqlite的值,例如unicode(filename)来将我的应用程序切换到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")])

这里的代码应该长什么样?


看起来这段代码,在你更新问题后,实际上并不是导致错误的代码,对吧? - metamatt
没错,在应用程序的后面有类似的代码。 - Naftuli Kay
5个回答

14

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


我尝试过这样做,但似乎我仍然会得到上面提到的那些错误。我已经更新了帖子,您可以看到我现在正在做什么。谢谢! - Naftuli Kay
我的错,我的脚本后面还有一些错误的转换,导致了相同的错误 :) - Naftuli Kay

3
你应该将SQL语句的参数作为Unicode传递。
现在,一切都取决于你如何获取文件名列表。也许你正在使用os.listdiros.walk读取文件系统?如果是这种情况,有一种方法可以直接将文件名作为Unicode传递给这些函数之一:
例如:

  • os.listdir(u'.')
  • os.walk(u'.')
当然,你可以用实际的目录替换u'.'。只要确保它是一个Unicode字符串即可。

1

你尝试直接传递Unicode字符串了吗:

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

在脚本的开头,你需要添加文件编码。
# coding: utf-8

如果我尝试这个,它似乎有效。但当我迭代约3000个文件时,它会在文件名为“02-Neighborhood #2(Laïka).mp3”时失败。我是否错过了某种转换技术? - Naftuli Kay

1
你已经明白了,但是:
我认为你实际上无法从cursor.execute("select * from musiclibrary where absolutepath = ?;", [filename.decode("utf-8")])中获取ProgrammingError异常,就像问题目前所述的那样。
要么utf-8解码会失败,要么cursor.execute调用将对结果满意。

-1

尝试更改为这个:

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

如果您的文件名没有使用utf8编码,请将utf8更改为您的编码方式。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接