【发布时间】:2018-06-13 17:46:44
【问题描述】:
我想通过在 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。当storage为0时,用户会收到“storage is zero now, can reply decr action”信息。
当我在 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 的返回类型是否不同导致了这个异常?
我应该遵循什么好的调试方法来调试这个脚本?
----编辑----
感谢我的同事 Carol,我更改了下面的代码并得到了正确的结果:
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)
这里还有一个问题,我们丢弃了local storage变量,直接使用了redis.call('get','storage')。 所以我不知道为什么本地存储不能做这些事情。需要更多的工作。
感谢 Kevin,终于可以运行下面的代码了:
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)
因为一开始storage是nil,但是把nil放在if语句中,它会返回false,所以我们需要把nil改成false。
【问题讨论】: