我试图在PostgreSQL中以压缩二进制形式存储字典。原因是这个字典对象有一天可能会变得太大(数亿个值)。
我找到了这个代码段:https://djangosnippets.org/snippets/2014/并将其更改为:
class CompressedBinaryField(models.BinaryField):
__metaclass__ = models.SubfieldBase
def to_python(self, value):
if not value:
return value
try:
return value.decode('bz2').decode('utf-8')
except Exception:
return value
def get_prep_value(self, value):
if not value:
return value
try:
value.decode('bz2')
return value
except Exception:
try:
tmp = value.encode('utf-8').encode('bz2')
except Exception:
return value
else:
if len(tmp) > len(value):
return value
return tmp
我用这个命令存储字典:
_dict = {}
MyModel.objects.create(
user=user,
data=repr(_dict), # data is a CompressedBinaryField.
)
这很有效。
然而,当我检索对象并尝试使用这样的命令时:
item = MyModel.objects.get(user=user)
curr_dict = eval(item.data)
我收到此错误:
TypeError('eval() arg 1 must be a string or code object',)
我认为item.data
出于某种原因是缓冲型对象。
我做错了什么?
答案 0 :(得分:2)
我建议您查看pickle
field for object serialization in Python数据转换为字节流并存储的内容。
pickle模块实现了一个基本但强大的算法,用于序列化和反序列化Python对象结构。 “Pickling”是将Python对象层次结构转换为字节流的过程,“unpickling”是反向操作,从而将字节流转换回对象层次结构。酸洗(和涂抹)也称为“序列化”,“编组”,1或“展平”,但为了避免混淆,这里使用的术语是“酸洗”和“涂抹”。
要检索数据,您将“破解”。
还有一个被广泛使用的django app called django-picklefield
。
你的方法的缺点是,你必须考虑到这么多方面。此外,建议不要使用eval
来保证安全性等。