I want to decrease my storage by using redis lua script in python, my code below:
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)
Above code is simple, it's a lua script to control the good storage, if the good didn't have the storage, the script will set its stroage to 10, when user access this script, the storage will decrease by 1 until to 0. When the storage is 0, then user will get "storage is zero now, can reply decr action" message.
When I ran this method in python, I got below exception:
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
I tried to figure out the problem, but couldn't find it out. For the above code itself, I don't think that there are some errors in it(I followed this answer to write my code). The only thing I want to be sure is that, whether the return type for redis and lua is different that caused this exception?
Any good debug method that I should follow to debug this script?
----EDIT----
Thx for my workmate Carol, I changed the code below and got the correct result:
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)
Here is another problem, we discard the local storage variable, directly used the redis.call('get','storage'). So I don't know why local storage won't do the stuff. Need more work on it.
Thx for Kevin, finally got the code run below:
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)
Because storage is nil at the first, but put nil in if statement, it will return false, thus we need change nil to false.