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
형식 값.
- HGET => 전달된 단일 키에 대한 값을 반환합니다.
- HSET => 단일 키에 대한 설정/해제 값
- HMGET => 전달된 단일/복수 키에 대한 값을 반환합니다.
- HMSET => 다중 키에 대한 값 설정/설정
- HGETALL => 매핑의 모든 (키, 값) 쌍을 반환합니다.
다음은 각각의 방법입니다.redis-py
라이브러리 :-
- HGET => hget
- HSET => hset
- HMGET => hmget
- HMSET => hmset
- 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-python 및 aioredis 사용
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에서 수행되었습니다.
- 네가 원한다면
{'field1': 'Hello', 'field2': 'World'}
사용하다
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"}'
그리고나서
# 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
'programing' 카테고리의 다른 글
pip로 패키지의 특정 버전을 설치하는 방법은 무엇입니까? (0) | 2023.08.06 |
---|---|
SQL Server에 데이터베이스 역할이 있는지 확인하는 방법은 무엇입니까? (0) | 2023.08.06 |
PowerShell에서 HTTP GET을 사용하려면 어떻게 해야 합니까? (0) | 2023.08.06 |
코틀린에서 지연 후 함수를 어떻게 호출합니까? (0) | 2023.08.01 |
CSS의 응답 글꼴 크기 (0) | 2023.08.01 |