如何使用由Flask-Cache创建的缓存值?

3
我正在一个应用程序中使用flask-cache,并尝试在单独的进程中预填充缓存。问题是我无法确定缓存值的格式。
查看缓存值时,它们看起来像已经被pickle处理过的,但被缓存函数创建的值与正常的pickle值有所不同,不能直接反pickle回来。下面是一个示例:
这是我的Flask视图函数:
@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.'

注意缓存的字节串有一个前导'!'。与手动pickling 'foo'进行比较:
>>> import pickle
>>> pickle.dumps('foo')
b'\x80\x03X\x03\x00\x00\x00fooq\x00.'

后者可以被反序列化,但尝试反序列化flask-cache值会导致错误"_pickle.UnpicklingError: invalid load key, '!'."由于我不完全理解问题,因此不愿意实施解决方案(例如删除/添加所有字节字符串上的"!")。我这么做正确吗?
1个回答

3

原始答案(Flask 1.0之前)

根据 werkzeug.contrib.cache.RedisCache code

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

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

更新:Flask 1+(cachelib.redis.RedisCache

RedisCache 后端现在在 这里,但序列化已移动到单独的类 {{link2:RedisSerializer}} 中。

存储略有不同。注释保持不变,但现在它只是将所有内容都进行了 pickles 序列化。

def dumps(self, value: _t.Any, protocol: int = pickle.HIGHEST_PROTOCOL) -> bytes:
    """Dumps an object into a string for redis. By default it serializes
    integers as regular string and pickle dumps everything else.
    """
    return b"!" + pickle.dumps(value, protocol)

这正是我正在寻找的。谢谢! - daveruinseverything
代码链接已损坏,请尽快更新。谢谢。 - Blaskovicz
@Blaskovicz 谢谢!已更新旧链接并添加新链接。 - twil

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接