19

我玩过烧瓶微框架,并想在 redis 中缓存一些统计信息。假设我有这个字典:

mydict = {}
mydict["test"] = "test11"

我把它保存到redis

redis.hmset("test:key", mydict)

不过还原后

stored = redis.hgetall("test:key")
print(str(stored))

我觉得很奇怪{b'test': b'test11'},所以stored.get("test")给了我 None

mydictstr 方法结果看起来不错{'test': 'test11'}。那么,为什么要将这个二进制标记添加到恢复的数据中呢?我还检查了 redis-cli 并没有在那里看到明确的 b 标记。hgetall 有问题吗?

4

3 回答 3

28

这是预期的行为。默认情况下,来自 Redis 的字符串不会被解码。你有几个选择:

  • 自己解码数据。
  • 使用参数创建一个客户端实例decode_responses,例如StrictRedis(decode_responses=True). charset这将根据参数(默认为 utf-8)解码来自 Redis 的所有字符串。只有这样做,您才能确定来自 Redis 的每个响应都有您想要解码为 utf-8 的字符串数据。如果您使用相同的客户端实例来获取二进制数据(例如腌制对象),则不应使用此选项。在这种情况下,我建议对二进制数据使用单独的客户端实例。

来源:https ://github.com/andymccurdy/redis-py/issues/463#issuecomment-41229918

于 2014-09-21T10:05:18.927 回答
9
POOL = redis.ConnectionPool(host='localhost', **decode_responses=True**, port=6379, db=0)
datastore = redis.StrictRedis(connection_pool=POOL)

如果使用 ConnectionPool,则应将 decode_responses=True 移动到 ConnectionPool 的构造函数中。

于 2017-02-22T05:27:23.547 回答
5

这是对 HGETALL 返回的 redis dict 执行字节解码的简单例程

def decode_redis(src):
    if isinstance(src, list):
        rv = list()
        for key in src:
            rv.append(decode_redis(key))
        return rv
    elif isinstance(src, dict):
        rv = dict()
        for key in src:
            rv[key.decode()] = decode_redis(src[key])
        return rv
    elif isinstance(src, bytes):
        return src.decode()
    else:
        raise Exception("type not handled: " +type(src))

...并使用,只需将它传递给redis dict ...

obj = decode_redis(redis_connection.hgetall(key))
于 2019-11-14T11:40:26.863 回答