How to remove a field in Tarantool space?

362 Views Asked by At

I have field in tarantool space I no longer need.

local space = box.schema.space.create('my_space', {if_not_exists = true})
space:format({
        {'field_1', 'unsigned'},
        {'field_2', 'unsigned'},
        {'field_3', 'string'},
})

How to remove field_2 if it's indexed and if it's not indexed?

1

There are 1 best solutions below

0
On BEST ANSWER

There is no any convenient way to do it.

The first way, just declare this field as nullable and insert NULL value to this field. Yes, it will be stored physically but you could hide them from users. It's simple and not expensive.

The second way, write in-place migration. It's not possible if you have indexed fields after field you want to drop (in your example it's field_3). And it's dangerous if you have a huge amount of data in this space.

local space = box.schema.space.create('my_space', {if_not_exists = true})
space:create_index('id', {parts = {{field = 1, type = 'unsigned'}}})
space:format({
    {'field_1', 'unsigned'},
    {'field_2', 'unsigned'},
    {'field_3', 'string'},
})

-- Create key_def instance to simplify primary key extraction
local key_def = require('key_def').new(space.index[0].parts)

-- drop previous format
space:format({})

-- Migrate your data
for _, tuple in space:pairs() do 
    space:depete(key_def:extract_key(tuple))
    space:replace({tuple[1], tuple[3]})
end

-- Setup new format
space:format({
    {'field_1', 'unsigned'},
    {'field_3', 'string'},
})

The third way is to create new space, migrate data into it and drop previous. Still it's quite dangerous.

local space = box.schema.space.create('new_my_space', {if_not_exists = true})
space:create_index('id', {parts = {{field = 1, type = 'unsigned'}}})
space:format({
    {'field_1', 'unsigned'},
    {'field_3', 'string'},
})

-- Migrate your data
for _, tuple in box.space['my_space']:pairs() do 
    space:replace({tuple[1], tuple[3]})
end

-- Drop the old space
box.space['my_space']:drop()

-- Rename new space
local space_id = box.space._space.index.name:get({'my_new_space'}).id

-- In newer version of Tarantool (2.6+) space.alter method available
-- But in older versions you could update name via system "_space" space 
box.space._space:update({space_id}, {{'=', 'name', 'my_space'}})