Python 3.x redis-py和hgetall行为
我玩过flask微框架,想在redis中缓存一些数据。比如说,我有一句话:Python 3.x redis-py和hgetall行为,python-3.x,redis,redis-py,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}所以被存储了。get(“test”)没有给我任何信息 mydictstr方法结果看起来
mydict = {}
mydict["test"] = "test11"
我把它保存到了redis
redis.hmset("test:key", mydict)
但恢复后
stored = redis.hgetall("test:key")
print(str(stored))
我看到奇怪的{b'test':b'test11}
所以被存储了。get(“test”)
没有给我任何信息
mydict
str方法结果看起来很好{'test':'test11'}
。那么,为什么要将这个二进制标记添加到恢复的数据中呢?我还检查了redis cli,在那里没有看到显式的b标记。hgetall有什么问题吗
这是预期的行为。默认情况下,来自Redis的字符串
不要被解码。您有两个选择:
- 自己解码数据
- 使用
参数创建一个客户端实例,例如decode\u responses
。这将解码所有字符串 来自Redis的基于StrictRedis(decode\u responses=True)
参数的 至utf-8)。只有这样,你才能确定Redis的每一个回复都是正确的 要解码为utf-8的字符串数据。如果您使用的是相同的 客户端实例来获取二进制数据,如pickle对象,则 不应该使用此选项。在这种情况下,我建议使用单独的 二进制数据的客户端实例charset
如果使用ConnectionPool,应该将decode\u responses=True移动到ConnectionPool的构造函数。下面是一个简单的例程,用于对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))
如果有人对此感兴趣,下面是开发人员给出的答案:此参数没有文档记录,而且似乎不起作用:
python3
>import redis
>POOL=redis.ConnectionPool(host='localhost',port=6379,db=0)
>datastore=redis.StrictRedis(connection\u POOL=POOL,decode\u responses=True)
>>mydict={}
>mydict[“test”]=“test11”
>>datastore.hmset(“test:key”,mydict”)
>stored=datastore.hgetall(“test:key”)
>stored
谢谢你,朋友,但这个问题已经5.5岁了。@Tommi,明白了,但仍然可以帮助其他有同样问题的人
obj = decode_redis(redis_connection.hgetall(key))