Python 如何使用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

我将如何存储我的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_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
类型值执行基本操作

  • HGET=>返回传递的单个键的值
  • HSET=>设置/更新单个键的值
  • HMGET=>返回传递的单个/多个键的值
  • HMSET=>设置/更新多个键的值
  • HGETALL=>返回映射中的所有(键、值)对
  • 以下是它们在redis py库中各自的方法:-

  • HGET=>HGET
  • HSET=>HSET
  • HMGET=>HMGET
  • HMSET=>HMSET
  • HGETALL=>HGETALL
  • 如果映射不存在,上述所有setter方法都会创建映射。 如果映射中的mapping/key不存在,上述所有getter方法都不会引发错误/异常

    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')