该hmset功能可以设置每个字段的值,但我发现,如果值本身是一个复杂的结构化对象,从hget的价值回归是一个序列化的字符串,而不是原来的对象
如
images= [{'type':'big', 'url':'....'},
{'type':'big', 'url':'....'},
{'type':'big', 'url':'....'}]
redis = Redis()
redis.hset('photo:1', 'images', images)
i = redis.hget('photo:1', 'images')
print type(i)
i的类型是一个字符串,而不是一个对象蟒,是否有任何方式来手动除了解决这个问题解析每个字段?
Answer 1:
你不能在Redis的创建嵌套结构,这意味着你不能(例如)存储本地Redis的哈希地图中的本地Redis的列表。
如果你真的需要嵌套结构,您可能希望只存储一个JSON二进制大对象(或类似的东西)来代替。 另一种选择是存储的“ID” /关键,不同的Redis对象为地图键的值,但需要到服务器多次调用得到充分的对象。
Answer 2:
其实,你可以存储在使用内置模块redis的Python对象咸菜 。
下面是例子。
import pickle
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
obj = ExampleObject()
pickled_object = pickle.dumps(obj)
r.set('some_key', pickled_object)
unpacked_object = pickle.loads(r.get('some_key'))
obj == unpacked_object
Answer 3:
JSON实施例:
import json
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
images= [
{'type':'big', 'url':'....'},
{'type':'big', 'url':'....'},
{'type':'big', 'url':'....'},
]
json_images = json.dumps(images)
r.set('images', json_images)
unpacked_images = json.loads(r.get('images'))
images == unpacked_images
蟒蛇3:
unpacked_images = json.loads(r.get('images').decode('utf-8'))
images == unpacked_images
Answer 4:
我创建了一个库, SubRedis ,它可以让你创建Redis的更复杂的结构/层次。 如果你给它一个Redis的实例和一个前缀,它给你一个几乎完全有能力和独立的Redis实例。
redis = Redis()
photoRedis = SubRedis("photo:%s" % photoId, redis)
photoRedis.hmset('image0', images[0])
photoRedis.hmset('image1', images[1])
...
SubRedis刚刚结束了前面附加传给它作为前缀到平坦redis的数据结构的字符串。 我觉得这是我结束了Redis的做了很多的模式一个方便的包装 - 前面加上一些ID巢一些数据。
Answer 5:
您可以使用RedisWorks
库。
pip install redisworks
>>> from redisworks import Root
>>> root = Root()
>>> root.something = {1:"a", "b": {2: 2}} # saves it as Hash
>>> 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
Answer 6:
下面是围绕Redis的哪个泡菜/ unpickles数据结构一个简单的包装:
from redis import Redis
from collections import MutableMapping
from pickle import loads, dumps
class RedisStore(MutableMapping):
def __init__(self, engine):
self._store = Redis.from_url(engine)
def __getitem__(self, key):
return loads(self._store[dumps(key)])
def __setitem__(self, key, value):
self._store[dumps(key)] = dumps(value)
def __delitem__(self, key):
del self._store[dumps(key)]
def __iter__(self):
return iter(self.keys())
def __len__(self):
return len(self._store.keys())
def keys(self):
return [loads(x) for x in self._store.keys()]
def clear(self):
self._store.flushdb()
d = RedisStore('redis://localhost:6379/0')
d['a'] = {'b': 1, 'c': 10}
print repr(d.items())
# this will not work: (it updates a temporary copy and not the real data)
d['a']['b'] = 2
print repr(d.items())
# this is how to update sub-structures:
t = d['a']
t['b'] = 2
d['a'] = t
print repr(d.items())
del d['a']
# Here is another way to implement dict-of-dict eg d['a']['b']
d[('a', 'b')] = 1
d[('a', 'b')] = 2
print repr(d.items())
# Hopefully you do not need the equivalent of d['a']
print repr([{x[0][1]: x[1]} for x in d.items() if x[0][0] == 'a'])
del d[('a', 'b')]
del d[('a', 'c')]
如果你喜欢在Redis的(泡菜店它的二进制版本)明文可读的数据,你可以替换再版和pickle.loads与ast.literal_eval pickle.dumps。 对于JSON,使用json.dumps和json.loads。
如果你总是使用的是一个简单的字符串键,可以删除密钥的酸洗。
Answer 7:
你可以存储你的结构是,做一个“EVAL”从字符串转换为对象:
images= [{'type':'big', 'url':'....'},
{'type':'big', 'url':'....'},
{'type':'big', 'url':'....'}]
redis = Redis()
redis.hset('photo:1', 'images', images)
i = eval(redis.hget('photo:1', 'images'))
print type(i) #type of i should be list instead of string now
文章来源: how to store a complex object in redis (using redis-py)