如何使用bsddb3将(长)整数值写入Berkeley DB?

时间:2012-05-02 13:44:54

标签: python berkeley-db bsddb

我正在尝试使用Berkeley DB来存储频率表(即带有字符串键和整数值的哈希表)。该表将从Python中编写,更新和读取;所以我目前正在尝试使用bsddb3。看起来它会完成我想要的大部分工作,除非它看起来只支持字符串值?

如果我理解正确,Berkeley DB支持任何类型的二进制密钥和值。有没有办法使用bsddb3有效地将原始长整数传入/传出Berkeley DB?我知道我可以将值转换为字符串,这可能是我最终会做的,但是有更有效的方法吗?即通过存储'原始'整数?


背景:我目前正在处理一个大型(可能是几十个,如果不是数百个,数百万个密钥)频率表。目前这是使用Python字典实现的,但是当它开始交换到虚拟内存时我会中止脚本。是的我查看了Redis,但它将整个数据库存储在内存中。所以我即将尝试Berkeley DB。我应该能够通过使用短期内存缓存来提高创建效率。即创建一个内存中的Python字典,然后定期将其添加到主Berkeley DB频率表中。

2 个答案:

答案 0 :(得分:1)

您是否需要从python以外的语言中读取数据?如果没有,你可以在python长整数上使用pickle,并在你重新读取时取消它们。你可能(可能能够)使用shelve模块,这将自动执行此操作您。但即使不是,您也可以手动挑选和取消值。

>>> import cPickle as pickle
>>> pickle.dumps(19999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999, pickle.HIGHEST_PROTOCOL)
'\x80\x02\x8a(\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7fT\x97\x05p\x0b\x18J#\x9aA\xa5.{8=O,f\xfa\x81|\xa1\xef\xaa\xfd\xa2e\x02.'
>>> pickle.loads('\x80\x02\x8a(\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7fT\x97\x05p\x0b\x18J#\x9aA\xa5.{8=O,f\xfa\x81|\xa1\xef\xaa\xfd\xa2e\x02.')
19999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999L

答案 1 :(得分:0)

Python struct将Python 3中的整数转换为字节或Python 2中的字符串。根据您的数据,您可以使用 unsigned long long 或{{1}的不同打包格式}:

uint64_t

这将返回 bigendian struct.unpack('>Q', my_integer) 的字节表示形式,它与bsddb键值所需的词典顺序相匹配。您可以使用更智能的打包功能(请查看wiredtiger.intpacking)以节省空间。

您不需要Python缓存,请使用DBEnv.set_cache_max and set_cache