Как передать `keys_and_args` в функцию redis-py 'eval` и в скрипт lua - PullRequest
0 голосов
/ 22 сентября 2019

Я хочу передать несколько ключей и значений из python в скрипт lua через функцию eval redis, которая задокументирована как:

eval(script, numkeys, *keys_and_args)

Выполните Lua script, указав numkeys, к которому будет обращаться скрипт, а также имена ключей и значения аргументов в keys_and_args.Возвращает результат скрипта.

На практике используйте объект, возвращаемый register_script.Эта функция существует исключительно для завершения API Redis.

Я следую за этим ответом в качестве отправной точки.Этот сценарий увеличивает значения всех значений в отсортированном наборе, указанном 1. Поскольку я хочу указать значения для обновления (имена ключей) и счетчик приращений для каждого (значения аргумента), мой сценарий выглядит следующим образом:

-- some logging
local loglist = "lualog"
redis.pcall("DEL", loglist)

local function logit(msg)
  redis.pcall("RPUSH", loglist, msg)
end

logit("started")

-- count & log the keys provided
local countofkeys = table.getn(KEYS)
logit(countofkeys)

-- loop through each key and increment
for n = 1, countofkeys do
  redis.call("zincrby", "test_set", ARGV[n], KEYS[n])
end

Я могу запустить это из командной строки с помощью:

$ redis-cli --eval script.lua apple orange , 1 1

Затем в Python подтвердите, что значения увеличились:

>>> r.zrange('test_set', start = 0, end = -1, withscores=True)
[(b'apple', 1.0), (b'orange', 1.0)]

Однако яне знаю, как запустить это, используя eval:

>>> c.eval(script,1,{'orange':1,'apple':1})
redis.exceptions.DataError: Invalid input of type: 'dict'. Convert to a byte, string or number first.

>>> c.eval(script,2,'apple orange , 1 1')
redis.exceptions.ResponseError: Number of keys can't be greater than number of args

>>> c.eval(script,1,'apple orange , 1 1')
redis.exceptions.ResponseError: Error running script (call to f_aaecafd58b474f08bafa5d4fefe9db98a58b4084): @user_script:21:
 @user_script: 21: Lua redis() command arguments must be strings or integers 

В документации не слишком ясно, как должен выглядеть keys_and_args.Также на командной строке numkeys на самом деле не требуется по внешнему виду вещей.Кто-нибудь знает, как это должно выглядеть?

Бонусный вопрос: как избежать жесткого кодирования "test_set" в скрипт lua.

1 Ответ

0 голосов
/ 22 сентября 2019

*keys_and_args должен быть повторяемым (например, список) - использование звездочки в качестве префикса к имени аргумента - это Pythonic способ сказать это.

Бонусный совет: посмотрите на redis-pyПомощник сценария.

Бонусный ответ: любые имена клавиш, к которым обращается сценарий, необходимо указывать в таблице KEYS.Ваш сценарий делает все неправильно - прочитайте документацию о EVAL.

Кроме того, в командной строке numkeys на самом деле не требуется для внешнего вида

Это только при использовании cli таким образом - разделение запятой (',') между именами ключей и аргументами.

...