如何在redis中存储复杂对象(使用redis-py)
hmset函数可以设置每个字段的值,但是我发现如果值本身是一个复杂的结构化对象,则从hget返回的值是一个序列化的string,而不是原始对象
例如
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)
我的types是一个string,而不是一个Python对象,有没有什么办法来解决这个问题,除了手动parsing每个字段?
您不能在Redis中创build嵌套结构,这意味着您不能(例如)在原生redis哈希映射中存储本地重做列表。
如果你真的需要嵌套结构,你可能只想存储一个JSON-blob(或类似的东西)。 另一种方法是将“id”/ key存储到不同的redis对象中作为map key的值,但这需要多次调用服务器才能获得完整的对象。
实际上,您可以使用内置的模块pickle将 redo中的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
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
python 3:
unpacked_images = json.loads(r.get('images').decode('utf-8')) images == unpacked_images
我创build了一个库SubRedis ,它可以让你在redis中创build更复杂的结构/层次结构。 如果你给它一个redis实例和一个前缀,它会给你一个几乎完全有能力和独立的redis实例。
redis = Redis() photoRedis = SubRedis("photo:%s" % photoId, redis) photoRedis.hmset('image0', images[0]) photoRedis.hmset('image1', images[1]) ...
SubRedis只是将传入的string作为前缀添加到平坦的redis数据结构中。 我发现这是一个方便的包装模式,我最终在redis中做了很多事情 – 使用一些id来嵌套一些数据。
您可以使用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
它将pythontypes转换为Redistypes,反之亦然。
>>> 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
你可以存储你的结构,并做一个“eval”从string转换为对象:
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