Redis:如何从 Lua 脚本中 HMSET 字典?

我试图将 Python 字典作为参数传递给 Lua 脚本,并从脚本中将其 HMSET 到 Redis 键中。

我有两个问题。

我应该如何将字典从 Python 传递到 Lua 脚本,然后从 Lua 脚本传递到 Redis?

将其传递给 Lua 似乎很简单,使用 json.dumps() 即可。但是,在 Lua 中如何将其转换回字典(或 Lua 表,我猜?)(我不能在 Redis 的 EVAL 中使用 Lua 的 require)。

虽然我仍然不知道如何将实际字典从 Lua 传递到 Redis,但我仍在尝试在 Lua 脚本中使用 HMSET 并尝试将字符串分配给键。

为什么我会收到此错误:

redis.exceptions.ResponseError:运行脚本时出错(调用 f_2591f0a1987b36dd027b752af3591c92be845cd4):
@user_script:7:@user_script:7:从 Lua 脚本调用 Redis 命令时的参数数目错误

鉴于我的 Lua 代码使用与我的 Python HMSET 相同的参数数目:

local key_name = KEYS[1]
redis.call('hmset', key_name, "some_val")
点赞
用户3160475
用户3160475

首先请注意,Pythonic的dict与Redis Hash不同:dict可以存储任何类型的值并支持嵌套,而hash只有1级深度并存储字符串。因此,如果您的dict嵌套和/或包含非字符串值,则映射是非平凡的。

现在,假设该dict确实是非嵌套的。

我应该如何将字典从Python传递到Lua脚本并从Lua脚本传递到Redis?

由于您正在传递JSON化的表示形式,因此可以使用Redis' Luacjson将其解析为Lua表,如下所示:

local dict = cjson.decode(ARGS[1])

我为什么会出现这个错误:

发生错误是因为您在没有字段名称参数的情况下调用了HMSET(顺便说一下,已经被“HSET”取代)。正确的做法(即将dict保存到hash中)可能如下所示:

local key_name = KEYS[1]
local dict = cjson.decode(ARGS[1])
for k, v in pairs(dict) do
  redis.call('HSET', key_name, k, v)
end

或者这个稍微更快一点的变体:

local key_name = KEYS[1]
local dict = cjson.decode(ARGS[1])
local payload = {}
for k, v in pairs(dict) do
  table.insert(payload, k)
  table.insert(payload, v)
end
redis.call('HSET', key_name, unpack(payload))
2019-11-24 14:22:43