Reputation: 916
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.
Upvotes: 3
Views: 2607
Reputation: 1
The error message explains the issue:
user_script:4: user_script:4: attempt to compare number with nil
Storage is a number can not compared to nil.
The code can be written like this:
"""
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
"""
Upvotes: 0
Reputation: 48952
According to the Redis Lua documentation, a nil
Redis value becomes a false
Lua value:
Redis Nil bulk reply and Nil multi bulk reply -> Lua false boolean type
Therefore, you should be comparing the result of the GET
to false
, not nil
. You're seeing this particular message because tonumber(false)
is nil
, which you're then comparing to a number, 0
.
Upvotes: 6