TL; DR для значений, возвращаемых cjson.decode()
, используйте cjson.null
для сравнения со значением null
в JSON.
Объяснение: Lua использует nil
в таблицах для отметки удаленных записей.Если JSONinc null
s будет преобразован в Lunatic nil
s, декодированные объекты будут повреждены.Следовательно, библиотека cjson использует облегченный тип пользовательских данных для представления null
/ nil
.
У вашего call_data есть поле date_created, которое имеет значение null - что вызывает ошибку.
Самое смешное, что Redis, как и Lua, не будет хранить значение nil / null, поэтому вам придется либо игнорировать нулевые значения, либо использовать специальное значение в Redis, чтобы пометить их.
Предполагая, что вы 'Я буду игнорировать их, вот один из способов:
local call_data = cjson.decode(ARGV[1])
local other_data = cjson.decode(ARGV[2])
local data = {}
local next = next
local null = cjson.null
local populate_data = function(source)
if next(source) == nil then
return
end
for property,value in pairs(source) do
if value ~= null then
redis.call('HSET', KEYS[2], property, value)
end
end
end
populate_data(call_data)
populate_data(other_data)
Кроме того, небольшая оптимизация будет заключаться в пакетном обновлении, например так:
local payload = {}
for property,value in pairs(source) do
if value ~= null then
table.insert(payload, property)
table.insert(payload, value)
end
end
redis.call('HSET', KEYS[2], unpack(payload))
PS, если хотите, посмотритев ReJSON , который я написал - он предназначен для того, чтобы помочь с тем, что вы пытаетесь сделать.