如何在Redis中存储复杂对象(使用redis-py)

8 浏览
0 Comments

如何在Redis中存储复杂对象(使用redis-py)

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的类型是一个字符串,而不是一个Python对象,除了手动解析每个字段之外,还有其他解决这个问题的方法吗?

0
0 Comments

在使用Redis存储复杂对象(使用redis-py)时,可能会遇到以下问题:当从Redis中获取数据时,返回的是bytes对象,而不是预期的字符串。这是因为Redis在存储数据时,会将其转换为字节流进行存储,而在读取数据时,返回的是字节流的表示。

为了解决这个问题,可以采用以下方法:

1. 使用JSON序列化:如果数据是JSON可序列化的,那么将数据转换为JSON字符串存储在Redis中可能是更好的选择。JSON是一种更常见的标准,不仅在Python之外更为通用,而且它本身更易读,并且避免了潜在的安全风险。

以下是使用JSON序列化存储和读取复杂对象的示例代码:

import json
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
images = [
    {'type':'big', 'url':'....'},
    {'type':'big', 'url':'....'},
    {'type':'big', 'url':'....'},
]
# 将Python字典对象转换为JSON字符串并保存到Redis中
json_images = json.dumps(images)
r.set('images', json_images)
# 从Redis中读取保存的JSON字符串并解析为Python字典对象
unpacked_images = json.loads(r.get('images'))
print(images == unpacked_images)  # 输出True

2. 解码bytes对象:如果在Python 3中使用`json.loads()`解析从Redis中获取的数据时,可能会遇到无法处理bytes对象的情况。此时,需要将从`redis.get()`返回的bytes对象解码为Python 3中的字符串。可以通过使用`.decode('utf-8')`方法来实现。

以下是在Python 3中解码bytes对象的示例代码:

unpacked_images = json.loads(r.get('images').decode('utf-8'))
print(images == unpacked_images)  # 输出True

另外,还可以在创建StrictRedis对象时,通过设置`decode_responses=True`参数来自动将返回的bytes对象解码为字符串。这样可以省略手动解码的步骤。

以上就是解决在Redis中存储复杂对象的问题的方法。通过使用JSON序列化和适当的解码操作,可以有效地存储和读取复杂对象,使其在Redis中具备更好的可读性和可操作性。

0
0 Comments

在Redis中,无法创建嵌套结构,也就是说无法在Redis哈希映射中存储本地Redis列表。如果确实需要嵌套结构,可以考虑存储JSON格式的数据,或者使用一个键来存储指向不同Redis对象的"ID"/键作为映射键的值,但这需要多次调用服务器以获取完整对象。

此外,还有一点需要注意:可以使用EVAL(服务器端Ruby脚本)创建奇怪的复合查询,具体可以参考Redis官方文档:redis.io/commands/eval

需求:如何在Redis中存储复杂对象(使用redis-py)?

Redis是一个流行的内存数据存储系统,但在Redis中存储复杂对象可能会遇到一些问题。在Redis中,无法创建嵌套结构,例如无法将本地Redis列表存储在本地Redis哈希映射中。这给我们存储复杂对象带来了一些挑战。

如果我们确实需要嵌套结构,一种解决方法是将对象序列化为JSON格式的字符串,并将该字符串存储在Redis中。这样可以保留对象的结构,并且可以在需要时将其还原为复杂对象。

另一种解决方法是将嵌套对象的ID或键存储为Redis哈希映射中的值,而不是存储对象本身。这样做需要多次调用Redis服务器来获取完整的对象,但可以在某些情况下提供更好的灵活性。

此外,Redis还提供了一种特殊的解决方法,即使用EVAL命令进行复合查询。通过使用服务器端的Ruby脚本,我们可以执行一些复杂的操作,以满足我们的需求。具体使用方法可以参考Redis官方文档中关于EVAL的说明。

当我们需要在Redis中存储复杂对象时,我们可以选择将对象序列化为JSON格式的字符串,或者将嵌套对象的ID/键存储为Redis哈希映射中的值。如果需要执行复杂操作,可以考虑使用EVAL命令进行服务器端脚本编写。这些方法可以帮助我们有效地存储和处理复杂对象。

0
0 Comments

如何在Redis中存储复杂对象(使用redis-py)

在使用Redis时,我们经常需要存储和检索复杂的Python对象。这些对象可能包含各种数据类型、嵌套结构和自定义类。然而,Redis本身只支持存储简单的数据类型,如字符串、整数和哈希等。那么,如何将复杂的Python对象存储到Redis中呢?

实际上,我们可以使用Python内置的pickle模块将Python对象存储到Redis中。pickle模块可以将Python对象序列化为字节流,并在需要时将其反序列化回对象。下面是一个示例代码:

import pickle
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
# 定义一个复杂的Python对象
obj = ExampleObject()
# 使用pickle将对象序列化为字节流
pickled_object = pickle.dumps(obj)
# 将序列化后的对象存储到Redis中
r.set('some_key', pickled_object)
# 从Redis中获取存储的对象,并使用pickle进行反序列化
unpacked_object = pickle.loads(r.get('some_key'))
# 检查原始对象和反序列化后的对象是否相等
obj == unpacked_object

上述代码使用pickle模块将ExampleObject对象序列化为字节流,并将其存储到Redis中。然后,我们可以通过从Redis中检索字节流并使用pickle进行反序列化,来获取原始的Python对象。

然而,需要注意的是,pickle的反序列化过程可以执行代码。这意味着,如果我们从不受信任的来源获取了序列化的对象并进行反序列化,可能会执行一些恶意代码。这是非常危险的,因为恶意代码可能会导致文件被删除等严重后果。

为了避免这种安全风险,我们可以考虑使用JSON作为替代方案。JSON是一种轻量级的数据交换格式,可以安全地序列化和反序列化Python对象。虽然JSON不支持所有的Python对象类型,但它是更可靠和安全的选择。

当然,如果我们确定从Redis中获取的对象是可信的,并且我们需要存储一些无法通过JSON序列化的特殊对象(如struct_time),我们仍然可以使用pickle。但是,为了提高性能,建议使用cPickle而不是pickle,因为cPickle具有更好的性能表现。

总结起来,我们可以使用pickle模块将复杂的Python对象存储到Redis中,但需要注意潜在的安全风险。如果可能,最好使用JSON作为替代方案。根据对象的特性和来源的可信度,选择合适的序列化和反序列化方法,以确保数据的完整性和安全性。

以上是关于如何在Redis中存储复杂对象(使用redis-py)的解决方法和注意事项。根据具体的需求和情况,选择合适的序列化方式,并注意安全性,以确保数据的可靠性和安全性。

0