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.
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();| Step | What it does | |
|---|---|---|
add_field({...}) / add_fields | Adds fields; options are the same as in create_schema. | |
update_field({...}) / update_fields | Changes 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().
# 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.
from('members').where({'name': 'Osman'}).fields('name', 'phone').get();update_field options#
| Option | Note |
|---|---|
type | Widening only: int8 → int16 → int32 → int64, uint8 → … → uint64, float32 → float64, string → text, date → datetime → timestamp. |
max_length, encoding, format, nullable, default, check | Same as create_schema. |
index | true / {name, unique} adds one, false drops it. |
rename | Renames the field. The field keeps its id, so records are not rewritten. |
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.
# 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.