redis-py and hgetall behavior

Tommi picture Tommi · Apr 24, 2014 · Viewed 14.5k times · Source

I played around with flask microframework, and wanted to cache some stats in redis. Let's say I have this dict:

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

I saved it to redis with

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

However after restore

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

I see weird {b'test': b'test11'} so stored.get("test") gives me None

mydict str method result looks fine {'test': 'test11'}. So, why this binary marker added to restored data? I also checked in redis-cli and don't see explicit b markers there. Something wrong with hgetall?

Answer

fnkr picture fnkr · Sep 21, 2014

This is the intended behavior. By default, strings coming out of Redis don't get decoded. You have a couple options:

  • Decode the data yourself.
  • Create a client instance with the decode_responses argument, e.g., StrictRedis(decode_responses=True). This will decode all strings that come from Redis based on the charset argument (which defaults to utf-8). Only do this is you're sure every response from Redis has string data that you want decoded to utf-8. If you're using the same client instance to get binary data such as a pickled object, you shouldn't use this option. In that case, I'd suggest using a separate client instance for the binary data.

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