redis-py和hgetall行为

Tom*_*mmi 12 redis python-3.x redis-py

我玩烧瓶微框架,并希望在redis中缓存一些统计数据.假设我有这个词:

mydict = {}
mydict["test"] = "test11"
Run Code Online (Sandbox Code Playgroud)

我把它保存到了redis

redis.hmset("test:key", mydict)
Run Code Online (Sandbox Code Playgroud)

但恢复后

stored = redis.hgetall("test:key")
print(str(stored))
Run Code Online (Sandbox Code Playgroud)

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

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

fnk*_*nkr 23

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

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

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

  • 这个参数没有记录,它似乎不起作用:`python3``>>> import redis``>>> POOL = redis.ConnectionPool(host='localhost', port=6379, db=0)` `> >> datastore = redis.StrictRedis(connection_pool=POOL, decode_responses=True)``>>> mydict = {}` `>>> mydict["test"] = "test11"` `>>> datastore.hmset(" test:key", mydict)` `True` `>>> stored = datastore.hgetall("test:key")` `>>> stored` `{b'test': b'test11'}` (3认同)

小智 5

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

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


Dar*_*ith 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))

Run Code Online (Sandbox Code Playgroud)

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

obj = decode_redis(redis_connection.hgetall(key))
Run Code Online (Sandbox Code Playgroud)

  • @Tommi,理解,但仍然可以帮助其他有同样问题的人 (10认同)