programing

redis를 사용하여 사전을 저장하고 검색하는 방법

padding 2023. 8. 6. 09:52
반응형

redis를 사용하여 사전을 저장하고 검색하는 방법

# I have the dictionary my_dict
my_dict = {
    'var1' : 5
    'var2' : 9
}
r = redis.StrictRedis()

내_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

당신은 할 수 있습니다.hmset(다음을 사용하여 여러 개의 키를 설정할 수 있습니다.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'}

받아쓰기를 선택하고 문자열로 저장할 수 있습니다.

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)

다른 사람들이 이미 기본적인 답변을 했듯이, 저는 여기에 몇 가지를 추가하고 싶습니다.

은 다은의명다니에 있는 입니다.REDIS본적인작수위해기행으로 기본적인 합니다.HashMap/Dictionary/Mapping형식 값.

  1. HGET => 전달된 단일 키에 대한 값을 반환합니다.
  2. HSET => 단일 키에 대한 설정/해제 값
  3. HMGET => 전달된 단일/복수 키에 대한 값을 반환합니다.
  4. HMSET => 다중 키에 대한 값 설정/설정
  5. HGETALL => 매핑의 모든 (키, 값) 쌍을 반환합니다.

다음은 각각의 방법입니다.redis-py라이브러리 :-

  1. HGET => hget
  2. HSET => hset
  3. HMGET => hmget
  4. HMSET => hmset
  5. HGETALL => hgetall

매핑이 없는 경우 위의 모든 세터 메서드가 매핑을 만듭니다.위의 모든 getter 메서드는 매핑/키가 존재하지 않는 경우 오류/예외를 발생시키지 않습니다.

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

상황을 좀 더 명확하게 해줬으면 좋겠어요.

Redis 문서에 따라 HMSET는 더 이상 사용되지 않습니다.이제 사용할 수 있습니다.HSET다음과 같은 사전을 사용합니다.

import redis

r = redis.Redis('localhost')
    
key = "hashexample" 
entry = { 
    "version":"1.2.3", 
    "tag":"main", 
    "status":"CREATED",  
    "timeout":"30"
}
r.hset(key, mapping=entry)

무의식적으로, 주의: 매무식적로으의우,,hset사전이 두 번째 위치(선택 사항) 인수로 전달되는 경우 사전을 수락하지 않습니다(사전을 수락하지 않음을 나타내는 오류 발생, [1] 참조).사전을 명명된 인수로 전달해야 합니다.mapping=.

[1] *** redis.exceptions.DataError: Invalid input of type: 'dict'. Convert to a bytes, string, int or float first.

python dict를 redis로 저장하려면 json 문자열로 저장하는 것이 좋습니다.

import 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를 사용하여 검색하는 동안 deserialize

data = r.get('key1')
result = json.loads(data)
arr = result['var3']

json 함수에 의해 직렬화되지 않은 유형(예: 바이트)은 어떻습니까?

json 함수로 직렬화할 수 없는 유형에 대해 인코더/디코더 함수를 작성할 수 있습니다.예를 들어 바이트 배열에 대한 base64/base 인코더/디코더 함수 쓰기.

다른은: 사할방: 용있수다니습을 사용할 수 .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

파이썬 유형을 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

redis에 의해 승인된 MessagePack을 사용하는 것을 고려할 수 있습니다.

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-pythonaioredis 사용

redis SET 명령은 임의 데이터가 아닌 문자열을 저장합니다.redis HSET 명령을 사용하여 딕트를 다음과 같은 형식의 redis 해시로 저장할 수 있습니다.

for k,v in my_dict.iteritems():
    r.hset('my_dict', k, v)

그러나 redis 데이터 유형과 python 데이터 유형은 정렬되지 않습니다.Python 딕트는 임의로 중첩될 수 있지만 redis 해시를 사용하려면 값이 문자열이어야 합니다.당신이 취할 수 있는 또 다른 접근법은 당신의 파이썬 데이터를 문자열로 변환하고 그것을 redis에 저장하는 것입니다.

r.set('this_dict', str(my_dict))

그런 다음 문자열을 꺼내면 python 객체를 다시 만들기 위해 문자열을 구문 분석해야 합니다.

다른 방법으로 문제에 접근할 수 있습니다.

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에서 데이터를 구성하는 방법을 정확히 모른다면 결과 구문 분석을 포함하여 몇 가지 성능 테스트를 수행했습니다.내가 사용한 사전 (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

보시다시피 두 번째 테스트에서는 hgetall(키)이 이미 딕트를 반환하지만 중첩된 딕트는 반환하지 않기 때문에 'info' 값만 구문 분석하면 됩니다.

그리고 물론, 파이썬의 딕트로 Redis를 사용하는 가장 좋은 예는 첫 번째 테스트입니다.

권장되지 않음 경고: Redis.hmset()이(가) 권장되지 않습니다.대신 Redis.hset()을 사용합니다.

HMSET는 더 이상 사용되지 않으므로 HSET를 사용할 수 있습니다.

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

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)

Nameko(Redis 백엔드를 자주 사용하는 Python microservices 프레임워크)의 경우 다음과 같이 hmset을 사용할 수 있습니다.

import uuid
from nameko.rpc import rpc
from nameko_redis import Redis

class AirportsService:
    name = "trips_service"
    redis = Redis('development')
    @rpc
    def get(self, trip_id):
        trip = self.redis.get(trip_id)
        return trip
    @rpc
    def create(self, airport_from_id, airport_to_id):
        trip_id = uuid.uuid4().hex
        pyDict = {"from":airport_from_id, "to":airport_to_id}
        self.redis.hmset(trip_id, pyDict)
        return trip_id

많은 좋은 답변들이 있었지만 이것은 저에게 효과가 있었습니다.

  • 스토어 사전
  • 사전을 구하다
  • 위의 다른 답변처럼 딕트를 키에서 필드로, 값에서 값으로 매핑하는 대신 중첩 해시를 사용합니다.(예 1 참조)
  • 모든 필드/값을 가져오고 딕트를 레디스 해시에 덤프하려는 프로젝트에서와 마찬가지로 딕트가 중첩 해시인 경우에도 마찬가지입니다(예 2 참조).

참고: 이러한 명령은 python repl에서 수행되었습니다.

  1. 네가 원한다면
{'field1': 'Hello', 'field2': 'World'}

enter image description here

사용하다

r = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True)
pdict = {'field1': 'Hello', 'field2': 'World'}
r.hmset("queues_test", pdict)

또한 다른 답변, 특히 Saji Xavier의 단순하고 효과적이기 때문에 참조하십시오.

다음과 같은 중첩 해시를 원하는 경우

{'queue1': '{"field1": "Hello", "field2": "World"}'

enter image description here

그리고나서

# to set
import json
r = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True)
pdict = {'field1': 'Hello', 'field2': 'World'}
pdict_string = json.dumps(pdict)
r.hset("queues_data", "queue1", pdict_string)

# to get a single field value
r.hget("queues_data", "queue1")
# '{"field1": "Hello", "field2": "World"}'

# to get all fields
data =  r.hgetall("queues_data")
# {'queue1': '{"field1": "Hello", "field2": "World"}'
queue1 = data['queue1']
queue1
# '{"field1": "Hello", "field2": "World"}'

result = json.loads(queue1)
result
# {'field1': 'Hello', 'field2': 'World'}
result['field1']
# 'Hello'

그러면 키/값만 필요하면 됩니다.

list(data.keys())
# ['queue1', 'queue2']

list(data.values())
# ['{"field1": "Hello", "field2": "World"}', '{"field1": "Hello", "field2": "World"}']

그런 다음 한 줄에 있는 모든 값에 대한 딕트를 다시 가져오려면 사용합니다.

lvalues = list(data.values()) 
# ['{"field1": "Hello", "field2": "World"}', '{"field1": "Hello", "field2": "World"}']

[json.loads(x) for x in lvalues]
# [{'field1': 'Hello', 'field2': 'World'}, {'field1': 'Hello', 'field2': 'World'}]

언급URL : https://stackoverflow.com/questions/32276493/how-to-store-and-retrieve-a-dictionary-with-redis

반응형