1

Just started learning Redis. Coming from EhCache background, few things are little confusing for me in Redis. This is what I want to achieve:

import redis


class User:

    def __init__(self, idd, name):
        self.id = idd
        self.name = name


cache = redis.Redis(host='localhost', port=6379, db=0)
#cache = redis.StrictRedis(host="localhost", port=6379, charset="utf-8", decode_responses=True)

user1 = User(1, 'john')
user2 = User(2, 'jack')

users_dict = {}
users_dict['1'] = user1
users_dict['2'] = user2

print(users_dict)

if not cache.exists('users'):
    cache.set('users', users_dict)

users_dict_retrieved = cache.get('users')
print(users_dict_retrieved)

print(users_dict_retrieved.get('1').name)

It should just print john as the output. Here is the output I get:

{'1': <__main__.User object at 0x103a71710>, '2': <__main__.User object at 0x103a71780>}
b"{'1': <__main__.User object at 0x103a71710>, '2': <__main__.User object at 0x103a71780>}"
Traceback (most recent call last):
  File "/Users/rishi/code/test.py", line 34, in <module>
    print(users_dict_retrieved.get('1').name)
AttributeError: 'bytes' object has no attribute 'get'

But I get AttributeError: 'bytes' object has no attribute 'get'. I understand this is because when the object is retrieved, it is in byte form. I tried using cache = redis.StrictRedis(host="localhost", port=6379, charset="utf-8", decode_responses=True) instead but it then converted objects representation to string as well. I also did some experimentation with hset and hget but that too went wrong. Any simple way of solving this? Or do I have to write object to string for storing and then use string to object after I retrieve?

rishi
  • 2,564
  • 6
  • 25
  • 47
  • 1
    I'm surprised any of this works. Can you please show *what* bytes object you get from Redis? Because you're saying you've managed to save a `dict` (let alone a custom class!) in Redis, something it doesn't support. When I try to run this code, I get an error on `set`. Are you sure there's no `users` in the database already, e.g. set manually or by some other program? – Norrius Jan 20 '19 at 20:51
  • @Norrius I edited my question with few prints. Also, I am sure there was nothing already set in DB. I ran redis-cli FLUSHALL from client before running this code – rishi Jan 21 '19 at 03:37
  • That's odd, but in any case, you'll need to serialise the data somehow. Your main options would be `json` and `pickle`, see [this question](https://stackoverflow.com/q/15219858/1983772) for some examples. – Norrius Jan 21 '19 at 20:45

1 Answers1

1

You should pass a dict object instead of a User object to your list. Example:

class User:

    def __init__(self, idd, name):
        self.id = idd
        self.name = name

    def to_dict(self):
        return self.__dict__
""" rest of code """

users_dict = {}
users_dict['1'] = user1.to_dict()
users_dict['2'] = user2.to_dict()
0e1val
  • 481
  • 3
  • 6