Question or problem about Python programming:
# I have the dictionary my_dict my_dict = { 'var1' : 5 'var2' : 9 } r = redis.StrictRedis()
How would I store my_dict and retrieve it with redis. For example, the following code does not work.
#Code that doesn't work r.set('this_dict', my_dict) # to store my_dict in this_dict r.get('this_dict') # to retrieve my_dict
How to solve the problem:
Solution 1:
You can do it by hmset
(multiple keys can be set using hmset
).
hmset("RedisKey", dictionaryToSet)
import redis conn = redis.Redis('localhost') user = {"Name":"Pradeep", "Company":"SCTL", "Address":"Mumbai", "Location":"RCP"} conn.hmset("pythonDict", user) conn.hgetall("pythonDict") {'Company': 'SCTL', 'Address': 'Mumbai', 'Location': 'RCP', 'Name': 'Pradeep'}
Solution 2:
you can pickle your dict and save as string.
import pickle import redis r = redis.StrictRedis('localhost') mydict = {1:2,2:3,3:4} p_mydict = pickle.dumps(mydict) r.set('mydict',p_mydict) read_dict = r.get('mydict') yourdict = pickle.loads(read_dict)
Solution 3:
Another way: you can use RedisWorks
library.
pip install redisworks
>>> from redisworks import Root >>> root = Root() >>> root.something = {1:"a", "b": {2: 2}} # saves it as Hash type in Redis ... >>> print(root.something) # loads it from Redis {'b': {2: 2}, 1: 'a'} >>> root.something['b'][2] 2
It converts python types to Redis types and vice-versa.
>>> root.sides = [10, [1, 2]] # saves it as list in Redis. >>> print(root.sides) # loads it from Redis [10, [1, 2]] >>> type(root.sides[1])
Disclaimer: I wrote the library. Here is the code: https://github.com/seperman/redisworks
Solution 4:
As the basic answer has already give by other people, I would like to add some to it.
Following are the commands in REDIS
to perform basic operations with HashMap/Dictionary/Mapping
type values.
- HGET => Returns value for single key passed
- HSET => set/updates value for the single key
- HMGET => Returns value for single/multiple keys passed
- HMSET => set/updates values for the multiple key
- HGETALL => Returns all the (key, value) pairs in the mapping.
Following are their respective methods in redis-py
library :-
- HGET => hget
- HSET => hset
- HMGET => hmget
- HMSET => hmset
- HGETALL => hgetall
All of the above setter methods creates the mapping, if it doesn’t exists.
All of the above getter methods doesn’t raise error/exceptions, if mapping/key in mapping doesn’t exists.
Example: ======= In [98]: import redis In [99]: conn = redis.Redis('localhost') In [100]: user = {"Name":"Pradeep", "Company":"SCTL", "Address":"Mumbai", "Location":"RCP"} In [101]: con.hmset("pythonDict", {"Location": "Ahmedabad"}) Out[101]: True In [102]: con.hgetall("pythonDict") Out[102]: {b'Address': b'Mumbai', b'Company': b'SCTL', b'Last Name': b'Rajpurohit', b'Location': b'Ahmedabad', b'Name': b'Mangu Singh'} In [103]: con.hmset("pythonDict", {"Location": "Ahmedabad", "Company": ["A/C Pri ...: sm", "ECW", "Musikaar"]}) Out[103]: True In [104]: con.hgetall("pythonDict") Out[104]: {b'Address': b'Mumbai', b'Company': b"['A/C Prism', 'ECW', 'Musikaar']", b'Last Name': b'Rajpurohit', b'Location': b'Ahmedabad', b'Name': b'Mangu Singh'} In [105]: con.hget("pythonDict", "Name") Out[105]: b'Mangu Singh' In [106]: con.hmget("pythonDict", "Name", "Location") Out[106]: [b'Mangu Singh', b'Ahmedabad']
I hope, it makes things more clear.
Solution 5:
If you want to store a python dict in redis, it is better to store it as json string.
import redis r = redis.StrictRedis(host='localhost', port=6379, db=0) mydict = { 'var1' : 5, 'var2' : 9, 'var3': [1, 5, 9] } rval = json.dumps(mydict) r.set('key1', rval)
While retrieving de-serialize it using json.loads
data = r.get('key1') result = json.loads(data) arr = result['var3']
What about types (eg.bytes) that are not serialized by json functions ?
You can write encoder/decoder functions for types that cannot be serialized by json functions. eg. writing base64/ascii encoder/decoder function for byte array.
Solution 6:
One might consider using MessagePack which is endorsed by redis.
import msgpack data = { 'one': 'one', 'two': 2, 'three': [1, 2, 3] } await redis.set('my-key', msgpack.packb(data)) val = await redis.get('my-key') print(msgpack.unpackb(val)) # {'one': 'one', 'two': 2, 'three': [1, 2, 3]}
Using msgpack-python and aioredis
Solution 7:
An other way you can approach the matter:
import redis conn = redis.Redis('localhost') v={'class':'user','grants': 0, 'nome': 'Roberto', 'cognome': 'Brunialti'} y=str(v) print(y['nome']) #<=== this return an error as y is actually a string conn.set('test',y) z=eval(conn.get('test')) print(z['nome']) #<=== this really works!
I did not test it for efficiency/speed.
Solution 8:
The redis SET command stores a string, not arbitrary data. You could try using the redis HSET command to store the dict as a redis hash with something like
for k,v in my_dict.iteritems(): r.hset('my_dict', k, v)
but the redis datatypes and python datatypes don't quite line up. Python dicts can be arbitrarily nested, but a redis hash is going to require that your value is a string. Another approach you can take is to convert your python data to string and store that in redis, something like
r.set('this_dict', str(my_dict))
and then when you get the string out you will need to parse it to recreate the python object.
Solution 9:
HMSET is deprecated. You can now use HSET with a dictionary as follows:
import redis r = redis.Redis('localhost') key = "hashexample" queue_entry = { "version":"1.2.3", "tag":"main", "status":"CREATED", "timeout":"30" } r.hset(key,None,None,queue_entry)
Solution 10:
Try rejson-py which is relatively new since 2017. Look at this introduction.
from rejson import Client, Path rj = Client(host='localhost', port=6379) # Set the key `obj` to some object obj = { 'answer': 42, 'arr': [None, True, 3.14], 'truth': { 'coord': 'out there' } } rj.jsonset('obj', Path.rootPath(), obj) # Get something print 'Is there anybody... {}?'.format( rj.jsonget('obj', Path('.truth.coord')) ) # Delete something (or perhaps nothing), append something and pop it rj.jsondel('obj', Path('.arr[0]')) rj.jsonarrappend('obj', Path('.arr'), 'something') print '{} popped!'.format(rj.jsonarrpop('obj', Path('.arr'))) # Update something else rj.jsonset('obj', Path('.answer'), 2.17)