sqlite3.ProgrammingError:除非使用可解释8位字节串的text_factory,否则不得使用8位字节串

R. *_*ill 87 python sqlite unicode zlib

在Python中使用SQLite3,我试图存储一段UTF-8 HTML代码的压缩版本.

代码如下所示:

...
c = connection.cursor()
c.execute('create table blah (cid integer primary key,html blob)')
...
c.execute('insert or ignore into blah values (?, ?)',(cid, zlib.compress(html)))
Run Code Online (Sandbox Code Playgroud)

在这一点上得到错误:

sqlite3.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.
Run Code Online (Sandbox Code Playgroud)

如果我使用'text'而不是'blob'并且不压缩HTML片段,那么它可以很好地工作(尽管db很大).当我使用'blob'并通过Python zlib库压缩时,我收到上面的错误消息.我环顾四周,但找不到这个简单的答案.

zag*_*zag 88

如果要在sqlite3中使用8位字符串而不是unicode字符串,请为sqlite连接设置approptiate text_factory:

connection = sqlite3.connect(...)
connection.text_factory = str
Run Code Online (Sandbox Code Playgroud)

  • 这可能会给您带来不同编码的问题,因为您仍在尝试将二进制数据解析为文本.最好使用sqlite3.Binary. (7认同)

R. *_*ill 35

找到解决方案,我应该花一点时间搜索.

解决方案是将值"转换"为Python'缓冲区',如下所示:

c.execute('insert or ignore into blah values (?, ?)',(cid, buffer(zlib.compress(html))))
Run Code Online (Sandbox Code Playgroud)

希望这会有助于其他人.

  • 这是不正确的,你应该使用sqlite3.Binary,正如文档所说. (3认同)

Mar*_*las 33

为了使用BLOB类型,必须首先将zlib压缩字符串转换为二进制数据 - 否则sqlite将尝试将其作为文本字符串处理.这是通过sqlite3.Binary()完成的.例如:

c.execute('insert or ignore into blah values (?, ?)',(cid, 
sqlite3.Binary(zlib.compress(html))))
Run Code Online (Sandbox Code Playgroud)

  • +1.这是**实际的**正确答案. (4认同)