Skip to content
NarDBv0.2.0-dev

alter_schema

Add, update, rename and drop fields and indexes.

alter_schema changes an existing schema. Steps can be written in any order; they are applied in the order they are written.

NarQL
alter_schema('members')
    .add_field({'phone': {type: string, max_length: 20, default: '-'}})
    .add_index({'surname': {name: 'idx_surname'}})
    .update_field({'name': {max_length: 80}, 'age': {type: int16}})
    .update_index({'idx_email': {name: 'idx_member_email'}})
    .commit();
StepWhat it does
add_field({...}) / add_fieldsAdds fields; options are the same as in create_schema.
update_field({...}) / update_fieldsChanges options of existing fields.
`add_index({'field': true \{name, unique}})`Adds an index and builds it from the existing rows.
update_index({'name': {unique, name}})Renames an index or changes its uniqueness.
drop_field('name')Drops a field, together with its indexes.
drop_index('name')Drops an index.
commit()Applies the change. Without it, the change is only validated.

Every successful alter_schema increases the schema's version by one. describe_schema -n members shows the current version.

Existing data#

Changes that affect existing rows are checked against every row before they are applied. The check also runs without .commit().

NarQL
# error: existing row ... violates the change: name: ... max_length is 3
alter_schema('members').update_field({'name': {max_length: 3}}).commit();

These changes are checked:

  • shortening max_length,
  • setting nullable: false,
  • adding a new check,
  • changing encoding,
  • adding a required field that has no default,
  • making an index unique.

A newly added field reads as its default in old rows, or as null if it has none. Records are not rewritten.

NarQL
from('members').where({'name': 'Osman'}).fields('name', 'phone').get();

update_field options#

OptionNote
typeWidening only: int8 → int16 → int32 → int64, uint8 → … → uint64, float32 → float64, string → text, date → datetime → timestamp.
max_length, encoding, format, nullable, default, checkSame as create_schema.
indextrue / {name, unique} adds one, false drops it.
renameRenames the field. The field keeps its id, so records are not rewritten.
NarQL
alter_schema('members')
    .update_field({'surname': {rename: 'last_name'}})
    .commit();

from('members').fields('name', 'last_name').get();

Narrowing changes (int64 → int8, string → int32) are rejected. Add a new field and copy the data instead.

NarQL
# error: age cannot change from int16 to string (it can widen to int32, int64)
alter_schema('members').update_field({'age': {type: string}}).commit();

(age was widened to int16 at the top of this page.)

The primary key, autoincrement and guid cannot change after a field is created. The primary key cannot be dropped or added later.