redis-py和hgetall行为

时间:2014-04-23 23:17:37

标签: python-3.x redis redis-py

我玩了一下flask微框架,想要在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")给了我无

mydict str方法结果看起来很好{'test': 'test11'}。那么,为什么这个二进制标记添加到恢复数据?我还检查了redis-cli并且没有在那里看到明确的b标记。 hgetall出了什么问题?

3 个答案:

答案 0 :(得分:22)

  

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

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

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

答案 1 :(得分:5)

POOL = redis.ConnectionPool(host='localhost', **decode_responses=True**, port=6379, db=0)
datastore = redis.StrictRedis(connection_pool=POOL)

如果您使用ConnectionPool,则应将decode_responses = True移至ConnectionPool的构造函数。

答案 2 :(得分:0)

这是一个简单的例程,可以对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))