Python-redis keys() returns list of bytes objects instead of strings

PythonRedis

Python Problem Overview


I'm using the regular redis package in order to connect my Python code to my Redis server.

As part of my code I check if a string object is existed in my Redis server keys.

string = 'abcde'
if string in redis.keys():
  do something..

For some reasons, redis.keys() returns a list with bytes objects, such as [b'abcde'], while my string is, of course, a str object.

I already tried to set charset, encoding and decode_responses in my redis generator, but it did not help.

My goal is to insert the data as string ahead, and not iterate over the keys list and change each element to str() while checking it.

Thanks ahead

Python Solutions


Solution 1 - Python

You can configure the Redis client to automatically convert responses from bytes to strings using the decode_responses argument to the StrictRedis constructor:

r = redis.StrictRedis('localhost', 6379, charset="utf-8", decode_responses=True)

Make sure you are consistent with the charset option between clients.

Note

You would be better off using the EXISTS command and restructuring your code like:

string = 'abcde'
if redis.exists(string):
    do something..

The KEYS operation returns every key in your Redis database and will cause serious performance degradation in production. As a side effect you avoid having to deal with the binary to string conversion.

Solution 2 - Python

If you do not wish to iterate the list for decoding, set your redis connection to automagically perform the decode and you'll receive your required result. As follows in your connection string, please notice the decode_responses argument:

rdb = redis.StrictRedis(host="localhost", port=6379, db=0, decode_responses=True)

Happy Coding! :-) (revised 13 Nov 2019)

Solution 3 - Python

One solution can be:

decode the redis key

print(key)
#output is : b'some_key'

print(key.decode())
#output is : 'some_key'

Updated :

Pass dictionary object into RedisPost class then decoding individual item and storing them as a object.

class RedisPost():
   def __init__(self, dic):
      for k,v in dic.items():
          if not isinstance(k,int):
             var = k.decode()
             setattr(self,var,v.decode())


my_dic = {'a':12, 'b':123}
obj = RedisPost(my_dic)
print(obj.a) # output will be 12 

Solution 4 - Python

Previous answers are correct in that the decode_responses connection parameter is needed to do this automatically, what they omit is that this needs to be set on the ConnectionPool instead if the connections are made using the pool. The below snippet will set the 'decode_responses' value on all clients to true, even if the client sets itself to False during connection

pool = redis.ConnectionPool(host=REDIS_HOST, port=REDIS_PORT, db=REDIS_DB, password=REDIS_PWD, decode_responses=True)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionGMeView Question on Stackoverflow
Solution 1 - PythonTague GriffithView Answer on Stackoverflow
Solution 2 - PythonRandallShanePhDView Answer on Stackoverflow
Solution 3 - PythonMuhammad Faizan FareedView Answer on Stackoverflow
Solution 4 - Pythonuser1596707View Answer on Stackoverflow