# I have the dictionary my_dict
my_dict = {
'var1' : 5
'var2' : 9
}
r = redis.StrictRedis()
¿Cómo almacenaría my_dict y lo recuperaría con redis? Por ejemplo, el siguiente código no funciona.
#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()
escritura como cadena y después de recuperarlos del usuario de redisjson.loads()
para deserializarlos de nuevo a la estructura de datos de Pythonjson.dumps()
yjson.loads()
solo funcionará si está de acuerdo con que las claves de su diccionario sean siempre cadenas. Si no es así, entonces podría considerar usar pickle.hmset
no le dice esto, pero genera un DataError si intenta almacenar un dict vacío.puede encurtir su dictado y guardarlo como cadena.
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)
fuente
pickle.loads
solo debe usarse en datos 100% confiablesOtra forma: puedes usar la
RedisWorks
biblioteca.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
Convierte tipos de Python en tipos de Redis y viceversa.
>>> 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'>
Descargo de responsabilidad: escribí la biblioteca. Aquí está el código: https://github.com/seperman/redisworks
fuente
hmset
bajo el capó si establece una variable en un dict, y por lo tanto, si lo haceroot.something = {}
, obtendrá un DataError, porquehmset
no permite diccionarios vacíos. Menciono esto porque la documentación de redis no te lo dice.hmset
. Voy a mirar en esto. @hlongmoreComo la respuesta básica ya la han dado otras personas, me gustaría agregarle algunas.
A continuación se muestran los comandos
REDIS
para realizar operaciones básicas conHashMap/Dictionary/Mapping
valores de tipo.Los siguientes son sus métodos respectivos en la
redis-py
biblioteca: -Todos los métodos de establecimiento anteriores crean el mapeo, si no existe. Todos los métodos getter anteriores no generan errores / excepciones, si el mapeo / clave en el mapeo no existe.
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']
Espero que aclare las cosas.
fuente
Si desea almacenar un diccionario de Python en redis, es mejor almacenarlo como una cadena 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)
Al recuperar la deserialización usando json.loads
data = r.get('key1') result = json.loads(data) arr = result['var3']
¿Qué pasa con los tipos (por ejemplo, bytes) que no están serializados por funciones json?
Puede escribir funciones de codificador / decodificador para tipos que las funciones json no pueden serializar. p.ej. escritura de la función codificador / decodificador base64 / ascii para matriz de bytes.
fuente
Se podría considerar el uso de MessagePack, que está respaldado por 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]}
Usando msgpack-python y aioredis
fuente
De otra forma puedes abordar el asunto:
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!
No lo probé por eficiencia / velocidad.
fuente
El comando redis SET almacena una cadena, no datos arbitrarios. Puede intentar usar el comando redis HSET para almacenar el dict como un hash de redis con algo como
for k,v in my_dict.iteritems(): r.hset('my_dict', k, v)
pero los tipos de datos redis y los tipos de datos python no se alinean del todo. Los dictados de Python se pueden anidar arbitrariamente, pero un hash de redis requerirá que su valor sea una cadena. Otro enfoque que puede tomar es convertir sus datos de Python en cadenas y almacenarlos en redis, algo como
r.set('this_dict', str(my_dict))
y luego, cuando saque la cadena, deberá analizarla para recrear el objeto de Python.
fuente
HMSET está obsoleto. Ahora puede usar HSET con un diccionario de la siguiente manera:
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)
fuente
Prueba rejson-py, que es relativamente nuevo desde 2017. Mira esta introducción .
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)
fuente
Si no sabe exactamente cómo organizar los datos en Redis, hice algunas pruebas de rendimiento, incluido el análisis de resultados. El diccionario que usé ( d ) tenía 437.084 claves (formato md5) y los valores de esta forma:
{"path": "G:\tests\2687.3575.json", "info": {"f": "foo", "b": "bar"}, "score": 2.5}
Primera prueba (insertando datos en una asignación de valor-clave de 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
Segunda prueba (insertando datos directamente en las claves de 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
Como puede ver, en la segunda prueba, solo se deben analizar los valores de 'información', porque hgetall (clave) ya devuelve un dict, pero no uno anidado.
Y, por supuesto, el mejor ejemplo de cómo usar Redis como dictados de Python es la Primera Prueba
fuente