【问题标题】:Pickling a django model with a binary field in cacheops在 cacheops 中使用二进制字段腌制 django 模型
【发布时间】:2014-07-07 11:49:36
【问题描述】:

我有一个简单的 Django 模型,其中包含一个我想腌制的二进制字段。

class MyModel(models.Model):
    bin_data = models.BinaryField()

根据我的单元测试的上下文,我执行以下操作:

import pickle
tmp_obj = MyModel.objects.create(bin_data="12345")
obj = MyModel.objects.get(pk=tmp_obj.pk)  # load from DB
data = pickle.dumps(obj)
obj2 = pickle.loads(data)

但是 pickle.dumps() 失败:

TypeError: can't pickle buffer objects

当我使用以下命令腌制时:

data = pickle.dumps(obj, protocol=-1)

转储成功但 pickle.loads() 失败:

TypeError: buffer() takes at least 1 argument (0 given)

这实际上与我在使用 django-cacheops 库时遇到的问题有关,该库用于缓存我的查询集。

在后台 django-cacheops 使用 pickle.dumps(obj, protocol=-1),我收到与上述 pickle.loads() 相同的错误

我会很感激 pickle 问题和 django-cacheops 问题的答案。

谢谢

【问题讨论】:

    标签: django pickle


    【解决方案1】:

    我设法解开了这个谜团,所以我不妨帮助任何可能遇到它的人。

    这个问题显然与 python 2.7 中的 pickle 模块中的一个错误有关,该错误不会被修复...... http://bugs.python.org/issue8323

    简而言之,pickle 库(使用最新协议时)能够腌制缓冲区类型,但不能取消腌制它们。

    在 django 模型中使用 BinaryField 时,从数据库加载时模型实例中的字段类型是“缓冲区”,这会导致问题。

    一个简单的解决方法是将“buffer”字段转换为“str”。

    对于我的示例,这可以使用 post_init 信号轻松完成:

    class MyModel(models.Model):
        bin_data = models.BinaryField()
    
    
    from django.db.models.signals import post_init
    
    def on_model_load(sender, **kwargs):
        model_obj = kwargs.get('instance', None)
        if model_obj and model_obj.bin_data is not None:
            model_obj.bin_data = str(model_obj.bin_data)
    
    post_init.connect(on_model_load, sender=MyModel)
    

    解决方法将允许对模型实例进行酸洗,并修复 django-cacheops 模块的行为。

    【讨论】:

    • 在 Python 3.4.1、django-cache-machine 0.9.1 和 Django 1.85 中遇到了同样的问题。这解决了它!我没有使用 cacheops。
    【解决方案2】:

    固定在cacheops 2.1.1

    以这种方式使用外部酸洗功能进行缓冲区:

    import copy_reg
    copy_reg.pickle(buffer, lambda b: (buffer, (bytes(b),)))
    

    【讨论】:

    • 更好。 cacheops 库中的修复!谢谢你:)
    猜你喜欢
    • 2010-10-05
    • 1970-01-01
    • 1970-01-01
    • 2018-06-15
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    • 2010-09-13
    • 2018-01-30
    相关资源
    最近更新 更多