Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

redis-py and hgetall behavior

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?

like image 900
Tommi Avatar asked Apr 23 '14 23:04

Tommi


People also ask

What is the difference between hgetall and hkeys in Redis?

The Redis command HGETALL retrieves all the keys and their values present in a hash. The redis-py returns the keys and values as a Python dictionary. The Redis command HKEYS retrieves all the keys present in a hash. The redis-py returns the keys as a Python list.

What is the Redis protocol in Python?

Implementation of the Redis protocol. This abstract class provides a Python interface to all Redis commands and an implementation of the Redis protocol. Pipelines derive from this, implementing how the commands are sent and received to the Redis server.

How do I add values to a Redis hash in Python?

Adding values to a Redis Hash and retrieving them using Python and Redis-Py: The HSET command adds a key-value pair to a hash. The HGET command retrieves the value for a specific key in a hash. The Redis command HGETALL retrieves all the keys and their values present in a hash. The Redis command HKEYS retrieves all the keys present in a hash.

How to avoid blocking behavior in Redis?

To avoid blocking behavior the commands SCAN and HSCAN can be used which allow only a small number of elements to be retrieved on each call. The keys and values present in the Redis hash are: The Redis command HDEL removes a key-value pair identified by a specific key.


2 Answers

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

like image 74
fnkr Avatar answered Sep 19 '22 15:09

fnkr


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

if you use the ConnectionPool, you should move the decode_responses=True to the constructor of ConnectionPool.

like image 45
mark gu Avatar answered Sep 18 '22 15:09

mark gu