使用python将压缩字符串存储到sqlite数据库中

问题描述 投票:0回答:3

我正在尝试在我的 sqlite 数据库中存储压缩字典。首先,我使用

json.dumps
将字典转换为字符串,这似乎工作正常。将此字符串存储在数据库中也可以。

在下一步中,我将使用

encode("zlib")
压缩字符串。但是将结果字符串存储在我的数据库中会引发错误。

mydict = {"house":"Haus","cat":"Katze","red":u'W\xe4yn',"dict":{"1":"asdfhgjl ahsugoh ","2":"s dhgsuoadhu gohsuohgsduohg"}}
dbCommand("create table testTable (ch1 varchar);")
# convert dictionary to string
jch1 = json.dumps(mydict,ensure_ascii=True)
print(jch1)
# store uncompressed values
dbCommand("insert into testTable (ch1) values ('%s');"%(jch1))
# compress json strings
cjch1 = jch1.encode("zlib")
print(cjch1)
# store compressed values
dbCommand("insert into testTable (ch1) values ('%s');"%(cjch1))

第一个打印输出:

{"house": "Haus", "dict": {"1": "asdfhgjl ahsugoh ", "2": "s dhgsuoadhu gohsuohgsduohg"}, "red": "W\u00e4yn", "cat": "Katze"}

第二个打印当然是不可读的:

xワフ1テPCᆵyfᅠネノ õ

我之前需要做任何额外的转换吗?

期待任何帮助提示!

python json sqlite dictionary compression
3个回答
3
投票

让我们从后面来看这个问题:为什么要使用 gzip 编码?您认为需要节省数据库空间吗?您是否检查过字典字符串将在生产中使用多长时间?这些字符串需要具有最小长度,然后压缩才能真正节省存储空间(对于小输入字符串,输出甚至可能大于输入!)。如果这确实节省了一些磁盘空间:您是否考虑过 gzip 编码和解码带来的额外 CPU 负载和处理时间是否值得节省的空间?

除此之外:gzip/zlib 压缩的结果是二进制 blob。在 Python 2 中,这应该是

str
类型。在 Python 3 中,这应该是类型
bytes
。无论如何,数据库需要知道您存储的任何内容都是二进制数据
VARCHAR
不是适合此任务的正确数据类型。以下是 MySQL 文档的引用:

此外,如果您想存储二进制值,例如来自 可能包含任意字节的加密或压缩函数 值,使用 BLOB 列而不是 CHAR 或 VARCHAR 列, 避免尾部空格删除可能发生变化的潜在问题 数据值。

同样的考虑也适用于其他数据库。另外,在 SQLite 的情况下,您必须使用 BLOB 数据类型(请参阅docs)来存储二进制数据(如果您想确保返回与之前输入的数据完全相同的数据:-))。


0
投票

非常感谢简·菲利普,

你向我展示了正确的解决方案。我的表需要有一个 BLOB 条目来存储数据。这是工作代码:

mydict = {"house":"Haus","cat":"Katze","red":u'W\xe4yn',"dict":{"1":"asdfhgjl ahsugoh ","2":"s dhgsuoadhu gohsuohgsduohg"}}
curs.execute("create table testTable (ch1 BLOB);")
# convert dictionary to string
jch1 = json.dumps(mydict,ensure_ascii=True)
cjch1 = jch1.encode("zlib")
# store compressed values
curs.execute('insert into testTable values (?);', [buffer(cjch1)])
db.commit()

0
投票

一个可能的替代方案(如果大多数行中有相对较大的字符串)可能是使用 Brotli 压缩

我最近创建了一个 sqlite-compressions ,它向 sqlite 添加了

gzip
brotli
压缩、解压缩和测试功能作为可加载扩展(或者您可以直接从 Rust 代码使用它)。加上另一个扩展中的许多哈希函数。

这将允许您使用 SQL 插入和检索原始数据,同时将其存储为 gzip 或 brotli blob:

  • INSERT INTO testTable (ch1) VALUES (brotli(?))
  • SELECT brotli_decode(ch1) FROM testTable
© www.soinside.com 2019 - 2024. All rights reserved.