使用 Python 2.7,我将 SQLite 中的网页存储到 BLOB 类型列中:
使用 zlib 进行压缩,我将其作为 sqlite3.Binary 类型插入。
没有压缩,效果很好:
db_body = sqlite3.Binary(page_body)
dbc.execute("insert into table (content) values ?", db_body)
压缩也能正常工作:
db_body = sqlite3.Binary(zlib.compress(page_body))
dbc.execute("insert into table (content) values ?", db_body)
当我尝试检索压缩数据时,问题就出现了。我尝试过以下方法:
dbc.execute("select content from table limit 1")
sql_result = dbc.fetchone()
page_content = zlib.decompress(sql_result[0])
但结果 (
page_content
) 是仍被压缩的 str 类型。没有错误或异常。 sql_result[0]
的内容类型是Buffer,因此解压缩函数正在更改数据类型,但不会更改内容。
如果我同时压缩和重新压缩,而不通过sqlite,输出就很好:
db_body = sqlite3.Binary(zlib.compress(page_body))
page_content = zlib.decompress(db_body)
那么,如何解压缩已插入然后从 SQLite 检索的数据?
您确定需要使用
sqlite3.Binary
吗?
db = sqlite3.connect('/tmp/mydb')
db.execute('CREATE TABLE tbl (bin_clmn BLOB)')
db.execute('INSERT INTO tbl VALUES(?)', [buffer(zlib.compress(page_body))])
db.commit()
db.close()
db = sqlite3.connect('/tmp/mydb')
row = db.execute('SELECT * FROM tbl').fetchone()
page_body_decompressed = zlib.decompress(str(row[0]))
print page_body == page_body_decompressed
我最近创建了一个 sqlite-compressions ,它向 sqlite 添加了
gzip
和 brotli
压缩、解压缩和测试功能作为可加载扩展(或者您可以直接从 Rust 代码使用它)。加上另一个扩展中的许多哈希函数。
这将允许您使用 SQL 插入和检索原始数据,同时将其存储为 gzip 或 brotli blob:
INSERT INTO tbl VALUES (gzip(?))
SELECT gzip_decode(bin_clmn) FROM tbl