Python 如何使用redis存储和检索词典
我将如何存储我的dict并使用redis检索它。例如,以下代码不起作用Python 如何使用redis存储和检索词典,python,redis,Python,Redis,我将如何存储我的dict并使用redis检索它。例如,以下代码不起作用 # I have the dictionary my_dict my_dict = { 'var1' : 5 'var2' : 9 } r = redis.StrictRedis() redis SET命令存储字符串,而不是任意数据。您可以尝试使用redis HSET命令将dict存储为redis散列,如下所示 #Code that doesn't work r.set('this_dict', my_di
# I have the dictionary my_dict
my_dict = {
'var1' : 5
'var2' : 9
}
r = redis.StrictRedis()
redis SET命令存储字符串,而不是任意数据。您可以尝试使用redis HSET命令将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
但是redis数据类型和python数据类型并不完全一致。Python dict可以任意嵌套,但redis哈希将要求您的值为字符串。您可以采取的另一种方法是将python数据转换为字符串,并将其存储在redis中,如
for k,v in my_dict.iteritems():
r.hset('my_dict', k, v)
然后,当您取出字符串时,您需要解析它以重新创建python对象。您可以pickle您的dict并另存为字符串
r.set('this_dict', str(my_dict))
您可以通过
hmset
(可以使用hmset
)设置多个键)
hmset(“重新索引”,字典集)
另一种方法:您可以使用RedisWorks库
pip安装redisworks
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'}
它将python类型转换为Redis类型,反之亦然
>>> 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
>root.sides=[10[1,2]]#将其保存为Redis中的列表。
>>>打印(根面)#从Redis加载
[10, [1, 2]]
>>>类型(根边[1])
免责声明:我写的图书馆。代码如下:如果要在redis中存储python dict,最好将其存储为json字符串
>>> 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'>
在检索时,使用json.loads对其进行反序列化
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函数序列化的类型(例如字节)呢
您可以为json函数无法序列化的类型编写编码器/解码器函数。例如,为字节数组编写base64/ascii编码器/解码器函数。由于其他人已经给出了基本答案,我想补充一些 以下是
REDIS
中的命令,用于对HashMap/Dictionary/Mapping
类型值执行基本操作
data = r.get('key1')
result = json.loads(data)
arr = result['var3']
我希望,这能让事情变得更清楚。尝试一下自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
conn=redis.redis('localhost')
v={'class':'user','grants':0,'nome':'Roberto','cognome':'Brunialti'}
y=str(v)
print(y['nome']#如果您不知道如何在Redis中组织数据,我会做一些性能测试,包括结果解析。
我使用的命令(d)有437.084个键(md5格式),此表单的值:
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键值映射):
第二次测试(将数据直接插入Redis键):
如您所见,在第二个测试中,只需解析“info”值,因为hgetall(键)已经返回了dict,但不是嵌套的dict
当然,使用ReiIS作为Python的DICTS的最好例子是<强>第一个测试<强>
< P> >可以考虑使用ReDIS认可的.< /P>
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
不推荐使用和HMSET。您现在可以将HSET与字典一起使用,如下所示:
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]}
弃用警告:Redis.hmset()已弃用。请改用Redis.hset()
由于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)
他可以将数据转换为json,并将结果存储在redis中,前提是它是嵌套的数据结构,而不是简单的dict,例如包含一些数组等。使用json.dumps()
write-as-string对数据进行序列化,并在从redis用户检索后json.loads()
将其反序列化回python数据结构json.dumps()
和json.loads()
只有在字典键始终是字符串的情况下才有效。如果您不是,那么您可以考虑使用CKEL。JSON与字节不兼容,因此JSON SeriTyt不是一个全局解决方案,例如,如果您有一个字节值的DICT,这将不起作用。但是,如果您试图存储一个空的dict,它会引发一个数据错误。@Pradeep我们如何使密钥动态。假设每15分钟插入一次数据,那么如何使密钥动态这是真的,但根据读写速率,这可能会增加严重的开销。pickle是一种缓慢的操作。请注意,如果将其用于服务器的用户输入,pickle.loads
is应仅用于100%可信数据。我对此进行了否决,因为某些dict无法序列化为JSON,例如,具有字节值的dict。您可以编写编码器/解码器函数(根据要求,例如base64/ascii编码)用于默认情况下无法编码/解码的类型。@Tommy-即使使用hmset/hgetall,您也可能需要编码/解码redis不支持的类型。不同意“…后一个操作是O(N)”N是链接到键的字段数。执行N SET/GET或1 HGET/HSET具有相同的复杂性。请参阅:从时间上看,HGET/HSET是原子事务,因此由REDIS执行得更快。您只需将复杂性从REDIS移动到Python代码。hmset的优点是可以仅检索dict的某些子部分.对于json,我们失去了这一点,因此这就像pickle或其他东西一样好。值得注意的是,如果您将变量设置为dict,那么RedisWorks会在后台使用hmset
,因此如果您
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
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
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]}
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)
import redis
r = redis.Redis(host='localhost', port=6379, decode_responses=True)
r.hset('user:23', mapping={'id': 23, 'name': 'ip'})
r.hgetall('user:23')