# I have the dictionary my_dict
my_dict = {
'var1' : 5
'var2' : 9
}
r = redis.StrictRedis()
Как мне сохранить my_dict и получить его с помощью redis. Например, следующий код не работает.
#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
json.dumps()
записи в виде строки и после получения от пользователя redisjson.loads()
для десериализации обратно в структуру данных pythonjson.dumps()
иjson.loads()
будет работать только в том случае, если вас устраивает то, что ключи словаря всегда являются строками. В противном случае вы можете рассмотреть возможность использования рассола.hmset
этого не говорится об этом, но возникает ошибка DataError, если вы пытаетесь сохранить пустой dict.вы можете замариновать свой диктант и сохранить как строку.
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)
источник
pickle.loads
его следует использовать только для 100% надежных данныхДругой способ: вы можете использовать
RedisWorks
библиотеку.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
Он преобразует типы Python в типы Redis и наоборот.
>>> 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]) <class 'list'>
Отказ от ответственности: я написал библиотеку. Вот код: https://github.com/seperman/redisworks
источник
hmset
под капотом, если вы устанавливаете переменную в dict, и, таким образом, если вы это сделаете,root.something = {}
вы получите DataError, потомуhmset
что не допускает пустых словарей. Я упоминаю об этом, потому что документация по Redis вам этого не говорит.hmset
. Я займусь этим. @hlongmoreПоскольку основной ответ уже был дан другими людьми, я хотел бы добавить к нему несколько слов.
Ниже приведены команды
REDIS
для выполнения основных операций соHashMap/Dictionary/Mapping
значениями типов.Ниже приведены их соответствующие методы в
redis-py
библиотеке: -Все вышеперечисленные методы установки создают отображение, если оно не существует. Все вышеперечисленные методы получения не вызывают ошибок / исключений, если сопоставление / ключ в сопоставлении не существует.
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']
Надеюсь, это проясняет ситуацию.
источник
Если вы хотите сохранить Python dict в Redis, лучше сохранить его как строку json.
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)
При извлечении де-сериализуйте его с помощью json.loads
data = r.get('key1') result = json.loads(data) arr = result['var3']
А как насчет типов (например, байтов), которые не сериализуются функциями json?
Вы можете написать функции кодировщика / декодера для типов, которые не могут быть сериализованы функциями json. например. запись функции кодировщика / декодера base64 / ascii для байтового массива.
источник
Можно подумать об использовании MessagePack, одобренного 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]}
Использование msgpack-python и aioredis
источник
Другой способ подойти к делу:
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!
На эффективность / скорость не тестировал.
источник
Команда redis SET сохраняет строку, а не произвольные данные. Вы можете попробовать использовать команду redis HSET, чтобы сохранить dict как хеш redis с чем-то вроде
for k,v in my_dict.iteritems(): r.hset('my_dict', k, v)
но типы данных redis и типы данных python не совсем совпадают. Python dicts может быть произвольно вложенным, но хэш Redis требует, чтобы ваше значение было строкой. Другой подход, который вы можете использовать, - это преобразовать данные Python в строку и сохранить ее в Redis, например
r.set('this_dict', str(my_dict))
а затем, когда вы получите строку, вам нужно будет проанализировать ее, чтобы воссоздать объект python.
источник
HMSET устарел. Теперь вы можете использовать HSET со словарем следующим образом:
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)
источник
Попробуйте rejson-py, который является относительно новым с 2017 года. Посмотрите это введение .
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)
источник
Если вы точно не знаете, как организовать данные в Redis, я провел несколько тестов производительности, включая анализ результатов. Словарь, который я использовал ( d ), имел 437,084 ключа (формат md5) и значения этой формы:
{"path": "G:\tests\2687.3575.json", "info": {"f": "foo", "b": "bar"}, "score": 2.5}
Первый тест (вставка данных в сопоставление "ключ-значение" redis):
conn.hmset('my_dict', d) # 437.084 keys added in 8.98s conn.info()['used_memory_human'] # 166.94 Mb for key in d: json.loads(conn.hget('my_dict', key).decode('utf-8').replace("'", '"')) # 41.1 s import ast for key in d: ast.literal_eval(conn.hget('my_dict', key).decode('utf-8')) # 1min 3s conn.delete('my_dict') # 526 ms
Второй тест (вставка данных непосредственно в ключи Redis):
for key in d: conn.hmset(key, d[key]) # 437.084 keys added in 1min 20s conn.info()['used_memory_human'] # 326.22 Mb for key in d: json.loads(conn.hgetall(key)[b'info'].decode('utf-8').replace("'", '"')) # 1min 11s for key in d: conn.delete(key) # 37.3s
Как видите, во втором тесте нужно анализировать только значения info, потому что hgetall (key) уже возвращает dict, но не вложенный.
И, конечно же, лучший пример использования Redis в качестве dicts Python - это First Test.
источник