Django:以压缩二进制格式存储字典

时间:2015-01-23 14:41:38

标签: django django-models

我试图在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出于某种原因是缓冲型对象。

我做错了什么?

1 个答案:

答案 0 :(得分:2)

我建议您查看pickle field for object serialization in Python数据转换为字节流并存储的内容。

  

pickle模块实现了一个基本但强大的算法,用于序列化和反序列化Python对象结构。 “Pickling”是将Python对象层次结构转换为字节流的过程,“unpickling”是反向操作,从而将字节流转换回对象层次结构。酸洗(和涂抹)也称为“序列化”,“编组”,1或“展平”,但为了避免混淆,这里使用的术语是“酸洗”和“涂抹”。

要检索数据,您将“破解”。

More info here

还有一个被广泛使用的django app called django-picklefield

你的方法的缺点是,你必须考虑到这么多方面。此外,建议不要使用eval来保证安全性等。