是否可以将嵌套的字典作为哈希结构存储在 Redis 中?
Is it possible to store nested dict in Redis as hash structure?
我正在尝试使用 HSET 将嵌套字典存储为散列,但这似乎不可能。
不的例子:
from redis import StrictRedis
foo = {
"host_data": {
"hostname": "some_host",
"mac_address": "82:fa:8e:63:40:05",
"root_password": {
"is_crypted": True,
"password": "sha512_password"
},
"network": {
"ip_address": "192.168.0.10/24",
"default_gateway": "192.168.0.1",
"vmnic": "vmnic3",
"vlan": 20
},
"dns_servers": [
"dns01.local",
"dns02.local"
]
},
"installation_type": "esxi",
"image_data": {
"type": "vCenter_contentlib",
"host": "vcenter01",
"credential": {
"username": "some_user",
"password": "some_password"
},
"content_library": "the_content_lib_name",
"image_name": "some_image"
},
"host_short_name": "esxi021"
}
redis_connection = StrictRedis(host='localhost', port=6379, charset="utf-8", decode_responses=True)
redis_connection.hset("test", mapping=foo)
抛出以下错误:
Traceback (most recent call last):
File "/Users/project/dummy.py", line 36, in <module>
redis_connection.hset("test", mapping=thing)
File "/Users/project/venv/lib/python3.9/site-packages/redis/client.py", line 3050, in hset
return self.execute_command('HSET', name, *items)
File "/Users/project/venv/lib/python3.9/site-packages/redis/client.py", line 900, in execute_command
conn.send_command(*args)
File "/Users/project/venv/lib/python3.9/site-packages/redis/connection.py", line 725, in send_command
self.send_packed_command(self.pack_command(*args),
File "/Users/project/venv/lib/python3.9/site-packages/redis/connection.py", line 775, in pack_command
for arg in imap(self.encoder.encode, args):
File "/Users/project/venv/lib/python3.9/site-packages/redis/connection.py", line 119, in encode
raise DataError("Invalid input of type: '%s'. Convert to a "
redis.exceptions.DataError: Invalid input of type: 'dict'. Convert to a bytes, string, int or float first.
有效的示例:
from redis import StrictRedis
foo = {
"installation_type": "esxi",
"host_short_name": "esxi021"
}
redis_connection = StrictRedis(host='localhost', port=6379, charset="utf-8", decode_responses=True)
redis_connection.hset("test", mapping=foo)
综上所述,我的问题是:
是否可以将嵌套的dict存储为Redis中的哈希结构?
注意:我知道它可以存储为字符串,然后加载为 json,但我真的想避免它。
编辑: Reids 版本为 6.2.5
没关系的问题,显然Redis只能使用扁平结构根据:https://redis.com/redis-best-practices/data-storage-patterns/object-hash-storage/
Redis 本身不会在散列中存储嵌套结构。关于如何解决 here.
有一个很好的答案
但是,有一个模块 RedisJSON that supports this and the python redis client 包含对此模块的支持。
在redis服务器中加载模块:
redis-server --loadmodule ../RedisJSON/target/release/librejson.dylib
在 python 中,您可以设置和检索嵌套的字典或部分路径。
import redis
from redis.commands.json.path import Path
redis_connection = StrictRedis(host='localhost', port=6379, charset="utf-8", decode_responses=True)
foo = {
"host_data": {
"hostname": "some_host",
"mac_address": "82:fa:8e:63:40:05",
"root_password": {
"is_crypted": True,
"password": "sha512_password"
},
"network": {
"ip_address": "192.168.0.10/24",
"default_gateway": "192.168.0.1",
"vmnic": "vmnic3",
"vlan": 20
},
"dns_servers": [
"dns01.local",
"dns02.local"
]
},
"installation_type": "esxi",
"image_data": {
"type": "vCenter_contentlib",
"host": "vcenter01",
"credential": {
"username": "some_user",
"password": "some_password"
},
"content_library": "the_content_lib_name",
"image_name": "some_image"
},
"host_short_name": "esxi021"
}
redis_connection.json().set("test", Path.rootPath(), foo)
print(redis_connection.json().get("test", '.host_data.hostname'))
我正在尝试使用 HSET 将嵌套字典存储为散列,但这似乎不可能。
不的例子:
from redis import StrictRedis
foo = {
"host_data": {
"hostname": "some_host",
"mac_address": "82:fa:8e:63:40:05",
"root_password": {
"is_crypted": True,
"password": "sha512_password"
},
"network": {
"ip_address": "192.168.0.10/24",
"default_gateway": "192.168.0.1",
"vmnic": "vmnic3",
"vlan": 20
},
"dns_servers": [
"dns01.local",
"dns02.local"
]
},
"installation_type": "esxi",
"image_data": {
"type": "vCenter_contentlib",
"host": "vcenter01",
"credential": {
"username": "some_user",
"password": "some_password"
},
"content_library": "the_content_lib_name",
"image_name": "some_image"
},
"host_short_name": "esxi021"
}
redis_connection = StrictRedis(host='localhost', port=6379, charset="utf-8", decode_responses=True)
redis_connection.hset("test", mapping=foo)
抛出以下错误:
Traceback (most recent call last):
File "/Users/project/dummy.py", line 36, in <module>
redis_connection.hset("test", mapping=thing)
File "/Users/project/venv/lib/python3.9/site-packages/redis/client.py", line 3050, in hset
return self.execute_command('HSET', name, *items)
File "/Users/project/venv/lib/python3.9/site-packages/redis/client.py", line 900, in execute_command
conn.send_command(*args)
File "/Users/project/venv/lib/python3.9/site-packages/redis/connection.py", line 725, in send_command
self.send_packed_command(self.pack_command(*args),
File "/Users/project/venv/lib/python3.9/site-packages/redis/connection.py", line 775, in pack_command
for arg in imap(self.encoder.encode, args):
File "/Users/project/venv/lib/python3.9/site-packages/redis/connection.py", line 119, in encode
raise DataError("Invalid input of type: '%s'. Convert to a "
redis.exceptions.DataError: Invalid input of type: 'dict'. Convert to a bytes, string, int or float first.
有效的示例:
from redis import StrictRedis
foo = {
"installation_type": "esxi",
"host_short_name": "esxi021"
}
redis_connection = StrictRedis(host='localhost', port=6379, charset="utf-8", decode_responses=True)
redis_connection.hset("test", mapping=foo)
综上所述,我的问题是:
是否可以将嵌套的dict存储为Redis中的哈希结构?
注意:我知道它可以存储为字符串,然后加载为 json,但我真的想避免它。
编辑: Reids 版本为 6.2.5
没关系的问题,显然Redis只能使用扁平结构根据:https://redis.com/redis-best-practices/data-storage-patterns/object-hash-storage/
Redis 本身不会在散列中存储嵌套结构。关于如何解决 here.
有一个很好的答案但是,有一个模块 RedisJSON that supports this and the python redis client 包含对此模块的支持。
在redis服务器中加载模块:
redis-server --loadmodule ../RedisJSON/target/release/librejson.dylib
在 python 中,您可以设置和检索嵌套的字典或部分路径。
import redis
from redis.commands.json.path import Path
redis_connection = StrictRedis(host='localhost', port=6379, charset="utf-8", decode_responses=True)
foo = {
"host_data": {
"hostname": "some_host",
"mac_address": "82:fa:8e:63:40:05",
"root_password": {
"is_crypted": True,
"password": "sha512_password"
},
"network": {
"ip_address": "192.168.0.10/24",
"default_gateway": "192.168.0.1",
"vmnic": "vmnic3",
"vlan": 20
},
"dns_servers": [
"dns01.local",
"dns02.local"
]
},
"installation_type": "esxi",
"image_data": {
"type": "vCenter_contentlib",
"host": "vcenter01",
"credential": {
"username": "some_user",
"password": "some_password"
},
"content_library": "the_content_lib_name",
"image_name": "some_image"
},
"host_short_name": "esxi021"
}
redis_connection.json().set("test", Path.rootPath(), foo)
print(redis_connection.json().get("test", '.host_data.hostname'))