3

我在应用程序中使用烧瓶缓存并尝试在单独的进程中预填充缓存。问题是我无法弄清楚缓存值的存储格式。

查看缓存的值,它们看起来像是被腌制过的,但缓存函数创建的值与普通腌制值略有不同,不能直接取消腌制。这是一个例子:

这是我的烧瓶视图:

@app.route('/index')
@cache.cached(timeout=60)
def index():
    return 'foo'

这是我认为存储在redis中的缓存值:

>>> r = redis.StrictRedis()
>>> r.keys()
[b'flask_cache_view//index']
>>> r.get('flask_cache_view//index')
b'!\x80\x03X\x03\x00\x00\x00fooq\x00.'

注意缓存的字节串有一个前导“!”。与手动酸洗 'foo' 相比:

>>> import pickle
>>> pickle.dumps('foo')
b'\x80\x03X\x03\x00\x00\x00fooq\x00.'

后者可以被 unpickle,但尝试 unpickle 烧瓶缓存值会导致错误“_pickle.UnpicklingError: invalid load key, '!'”。

因为我不完全理解问题,所以我不习惯实施解决方案(例如,在所有字节串上删除/添加“!”)。我在正确的轨道上吗?

4

1 回答 1

2

根据werkzeug.contrib.cache.RedisCache 代码

def dump_object(self, value):
    """Dumps an object into a string for redis.  By default it serializes
    integers as regular string and pickle dumps everything else.
    """
    t = type(value)
    if t in integer_types:
        return str(value).encode('ascii')
    return b'!' + pickle.dumps(value)

def load_object(self, value):
    """The reversal of :meth:`dump_object`.  This might be called with
    None.
    """
    if value is None:
        return None
    if value.startswith(b'!'):
        try:
            return pickle.loads(value[1:])
        except pickle.PickleError:
            return None
    try:
        return int(value)
    except ValueError:
        # before 0.8 we did not have serialization.  Still support that.
        return value

!用于区分整数和其他类型的值。

于 2015-08-19T12:06:35.097 回答