我想通过在python中使用redis lua脚本减少我的存储空间,我的代码如下:
def lua_storage():
conn = redis_conn()
lua = """
local storage = redis.call('get','storage')
if (storage ~= nil) then
if tonumber(storage) >= 0 then
return redis.call('decr','storage')
else
return 'storage is zero now, can reply decr action'
end
else
redis.call('set','storage',10)
end
"""
result = conn.eval(lua,0)
print(result)
上面的代码很简单,它是一个控制好存储的lua脚本,如果好的没有存储,脚本会将其stroage设置为10,当用户访问这个脚本时,存储将减少1直到当存储为0时,用户将获得“现在存储为零,可以回复decr动作”消息。
当我在python中运行此方法时,我得到以下异常:
Traceback (most recent call last):
File "D:/mytools/luaredis/mytest.py", line 53, in <module>
lua_storage()
File "D:/mytools/luaredis/mytest.py", line 47, in lua_storage
result = conn.eval(lua,0)
File "C:\Python27\lib\site-packages\redis\client.py", line 2067, in eval
return self.execute_command('EVAL', script, numkeys, *keys_and_args)
File "C:\Python27\lib\site-packages\redis\client.py", line 668, in execute_command
return self.parse_response(connection, command_name, **options)
File "C:\Python27\lib\site-packages\redis\client.py", line 680, in parse_response
response = connection.read_response()
File "C:\Python27\lib\site-packages\redis\connection.py", line 629, in read_response
raise response
redis.exceptions.ResponseError: Error running script (call to f_19dc8de385a024db32cb227ec869e8b644ebbc36): @user_script:4: user_script:4: attempt to compare number with nil
我试图弄清楚问题,但找不到它。 对于上面的代码本身,我不认为它有一些错误(我跟着this answer编写我的代码)。我唯一想确定的是,redis和lua的返回类型是否不同导致了这个异常?
我应该遵循调试此脚本的任何好的调试方法?
---- ---- EDIT
对于我的同事卡罗尔来说,我改变了下面的代码并得到了正确的结果:
def lua_storage():
conn = redis_conn()
lua = """
if redis.call('get','storage') then
if tonumber(redis.call('get','storage')) > 0 then
return redis.call('decr','storage')
else
return 'storage is zero now, can reply decr action'
end
else
redis.call('set','storage',10)
end
"""
result = conn.eval(lua,0)
print(result)
这是另一个问题,我们丢弃本地存储变量,直接使用 redis.call('get','storage')。 所以我不知道为什么本地存储不会做这些事情。需要做更多的工作。
凯文的Thx,终于得到了以下代码:
def lua_storage():
conn = redis_conn()
lua = """
local storage = redis.call('get','storage')
if storage ~= false then
if tonumber(storage) > 0 then
return redis.call('decr','storage')
else
return 'storage is zero now, can reply decr action'
end
else
return redis.call('set','storage',10)
end
"""
result = conn.eval(lua,0)
print(result)
因为存储在第一个时为nil,而在if语句中为nil,所以它将返回false,因此我们需要将nil更改为false。
答案 0 :(得分:2)
根据Redis Lua documentation,project editor
Redis值变为nil
Lua值:
Redis Nil批量回复和Nil多批量回复 - &gt; Lua false布尔类型
因此,您应该将false
与GET
的结果进行比较,而不是false
。您之后看到此特定邮件,因为nil
为tonumber(false)
,然后您与nil
号码进行比较。
答案 1 :(得分:0)
错误消息说明了问题:
user_script:4:user_script:4:尝试将数字与nil进行比较
存储是一个无法比较的数字。
代码可以这样写:
"""
if redis.call('get','storage') then
local storage = redis.call('get','storage')
if tonumber(storage) >= 0 then
return redis.call('decr','storage')
else
return 'storage is zero now, can reply decr action'
end
else
redis.call('set','storage',10)
end
"""