create_schema
Fields, types, lengths, character encodings and indexes.
A schema defines a table: its fields, types, rules and indexes.
create_schema('members')
.fields({
'id': {type: string, max_length: 32, guid: true, primary_key: true},
'name': {type: string, max_length: 50},
'surname': {type: string, max_length: 50, encoding: latin5},
'nickname': {type: string, max_length: 20, default: '🍉'},
'email': {type: string, max_length: 100, index: {unique: true, name: 'idx_email'}},
'age': {type: int8},
'seq': {type: int64, autoincrement: true},
'birth': {type: date, format: 'dd.mm.yyyy'},
'balance': {type: decimal, precision: 12, scale: 2, default: 0}
})
.commit();- Without
.commit()the schema is only validated. Errors come with a line and a column. - Field order is kept;
fields('*')returns fields in this order. - Every field gets an id that is never reused. Dropping a field and adding a new one cannot mix up old records.
- Names are lowercase
snake_case, at most 63 characters. The nameprivilegesand names starting withnar_are reserved.
To drop a schema:
drop_schema('members').commit();Dropping releases all of the table's pages.
Types#
| Group | Types |
|---|---|
| Integer | int8 int16 int32 int64 · uint8 uint16 uint32 uint64 |
| Floating point | float32 float64 · decimal (with precision, scale) |
| Text | string (default max_length: 255) · text (unbounded) |
| Boolean | bool |
| Time | date datetime time timestamp |
| Identifier | guid |
| Binary | binary blob |
A bare int is not accepted; the size has to be written. int8 only holds up to 127, so choosing it by accident makes values overflow.
# error: 'int' is ambiguous: write the size, e.g. int8 (−128..127), int32 or int64
create_schema('x').fields({'age': {type: int}});Field options#
| Option | What it does |
|---|---|
max_length | Upper limit for string and binary. Counts characters, not bytes. |
encoding | utf8 (default), ascii, latin1, latin5. See below. |
precision, scale | Total and fractional digits for decimal. |
format | Input and display format of date fields, e.g. 'dd.mm.yyyy'. |
nullable | Default true. Defaults to false for the primary key and for autoincrement and guid fields. |
default | A value, now(), guid() or null. |
primary_key | At most one field. Without one, a hidden row id is used. |
autoincrement | For integer fields. Cannot be combined with guid. |
guid | Generates ids for string (max_length ≥ 32) or the guid type. |
index | true or {name, unique}. Only btree for now. |
check | Validation rules; see Validation. |
Character encodings and emoji#
Text is always handled as UTF-8. encoding decides which characters a field accepts:
| Encoding | Accepts |
|---|---|
utf8 | All of Unicode, emoji included: 🍉 👩💻 🇹🇷 |
ascii | 7-bit characters only (codes, slugs, country codes) |
latin1 | Characters that ISO-8859-1 can represent |
latin5 | Characters that ISO-8859-9 can represent, including Turkish ğ ı ş İ Ğ Ş |
create_schema('tags')
.fields({
'slug': {type: string, max_length: 40, encoding: ascii, primary_key: true},
'name': {type: string, max_length: 40}
})
.commit();
from('tags').insert_one({slug: 'pomegranate-juice', name: 'Pomegranate juice 🍹'});# error: character 'ç' is not allowed in ascii
from('tags').insert_one({slug: 'çay', name: 'Tea'});max_length counts Unicode code points. 🍉 is one character; 👩💻 is three (two emoji and the joiner between them).
Date formats#
The schema's format and the FORMAT and TO_DATE functions use the same tokens:
| Token | Meaning | Token | Meaning |
|---|---|---|---|
yyyy | year (2026) | hh | hour (00–23) |
yy | year (26) | ii | minute |
mm | month | ss | second |
dd | day |
MM and HH mean the same as mm and hh. Separators are - / . : , T and space. Without a format, ISO 8601 is used. A date field cannot have time tokens.
Indexes#
The primary key is indexed automatically (pk_<schema>). For other fields:
create_schema('orders')
.fields({
'no': {type: int64, autoincrement: true, primary_key: true},
'member_id': {type: string, max_length: 32, index: true},
'code': {type: string, max_length: 20, index: {unique: true, name: 'idx_order_code'}}
})
.commit();When where searches the primary key or an indexed field with equality, the table is not scanned; rows are read straight from the index. In a unique index null values do not count as equal, so many rows can be null.