【问题标题】:redis-py and hgetall behaviorredis-py 和 hgetall 行为
【发布时间】:2022-01-24 01:27:57
【问题描述】:

我玩过烧瓶微框架,想在 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

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

【问题讨论】:

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


【解决方案1】:

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

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

来源: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)>>> datastore = redis.StrictRedis(connection_pool=POOL, decode_responses=True)>>> mydict = {}987654330@>>> datastore.hmset("test:key", mydict)True987654332@98765433@98765433 @{b'test': b'test11'}
【解决方案2】:
POOL = redis.ConnectionPool(host='localhost', **decode_responses=True**, port=6379, db=0)
datastore = redis.StrictRedis(connection_pool=POOL)

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

    • 谢谢你的朋友,但这个问题已经有 5.5 年历史了。
    • @Tommi,了解,但仍然可以帮助其他有同样问题的人
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-11
    • 2020-11-22
    • 2014-06-01
    • 2011-12-26
    • 2020-02-27
    • 1970-01-01
    • 2017-01-20
    相关资源
    最近更新 更多