Skip to main content

Schema reference

A table schema declares its fields, primary key, and optional foreign keys. This reference covers managed relational tables. TaruviBase stores a Frictionless descriptor with each table and maps it to a managed PostgreSQL table.

Storage and schema compatibility​

Every table records a storage mode and a schema format. The Database workflows in this documentation use:

SettingRequired value
Storage modeflat_table
Schema formatfrictionless
Materialization stateis_materialized: true

flat_table maps declared fields to PostgreSQL columns and supported constraints. A field declared as {"type":"object"} becomes one JSONB column inside the managed table. Whole-table JSONB storage follows a different record and query contract, so apply the SDK examples here only to tables that match the settings above.

Before applying these examples to an existing table, confirm that provider_type is flat_table, schema_format is frictionless, and is_materialized is true.

Descriptor​

{
"title": "Tasks",
"description": "Work tracked by the application",
"fields": [
{
"name": "id",
"type": "string",
"format": "uuid",
"constraints": {
"required": true
}
},
{
"name": "title",
"type": "string",
"constraints": {
"required": true,
"maxLength": 200
}
}
],
"primaryKey": ["id"],
"foreignKeys": []
}
PropertyTypePurpose
fieldsarrayFields stored in every record
primaryKeyarray containing one field nameField used to identify a record in SDK and REST operations
foreignKeysarrayConnections from local fields to another table
titlestringOptional display title
descriptionstringOptional explanation of the table

Declare primaryKey as an array, including when the table has one key.

Fields​

Every item in fields has a name and type:

{
"name": "priority",
"type": "integer",
"description": "Priority from 1 to 5",
"constraints": {
"required": true,
"minimum": 1,
"maximum": 5
}
}
PropertyRequiredPurpose
nameYesKey used in records and queries
typeYesLogical value type
formatNoType refinement, such as uuid for a string
arrayItemFor typed arraysDeclares the type stored in each array element
constraintsNoRequired, unique, length, range, or enum rules
descriptionNoHuman-readable field description
x-pg-typeFor range-family fieldsDeclares a PostgreSQL range or multirange type

Use names that start with a letter or underscore and contain only letters, numbers, and underscores. Lowercase snake_case is the recommended convention for every interface.

Field types​

For a managed flat table, these declarations produce:

Schema declarationPostgreSQL value
{"type":"string"}Text, or bounded text with maxLength
{"type":"string","format":"uuid"}UUID
{"type":"integer"}Integer
{"type":"number"}Numeric
{"type":"boolean"}Boolean
{"type":"date"}Date
{"type":"datetime"}Timestamp
{"type":"object"}PostgreSQL JSONB column containing a JSON object
{"type":"array"}PostgreSQL text array
{"type":"array","arrayItem":{"type":"integer"}}PostgreSQL big-integer array
{"type":"any","x-pg-type":"numrange"}PostgreSQL range

Managed flat tables also accept these provisioned field declarations:

DeclarationPostgreSQL value
{"type":"time"}Time
{"type":"year"}Integer year
{"type":"geojson"}JSONB

Text​

maxLength creates bounded text. minLength adds a minimum-length check:

{
"name": "code",
"type": "string",
"constraints": {
"minLength": 3,
"maxLength": 20
}
}

UUID​

Declare UUID values as strings with the uuid format:

{
"name": "id",
"type": "string",
"format": "uuid",
"constraints": {
"required": true
}
}

TaruviBase generates the UUID when it is omitted. Supply one with an SDK or REST write when the application owns record identity.

JSON objects​

Use object for a structured JSON value in an otherwise ordinary flat table. Database stores this field in a PostgreSQL JSONB column:

{
"name": "preferences",
"type": "object"
}

Send an object in the record payload, not an encoded JSON string. This field type is distinct from choosing the whole-table jsonb storage mode. Portable Database queries treat the object as one field. Promote values that need independent filtering or sorting into typed flat-table fields.

Arrays​

Use array with arrayItem when every element has a known type:

{
"name": "priority_ids",
"type": "array",
"arrayItem": {
"type": "integer"
}
}

Database maps these arrayItem.type values:

arrayItem.typePostgreSQL element type
stringText
integerBig integer
numberNumeric
booleanBoolean
dateDate
datetimeTimestamp

If arrayItem is omitted or its type is not recognized, TaruviBase uses text elements. Send the field value as a JSON array in record payloads.

PostgreSQL ranges​

Ranges use type: "any" with x-pg-type:

{
"name": "active_window",
"type": "any",
"x-pg-type": "tstzrange"
}

Database accepts these PostgreSQL range declarations:

Rangex-pg-type
Numericnumrange
Integerint4range
Big integerint8range
Datedaterange
Timestamptsrange
Timestamp with time zonetstzrange

Use the range declarations above when an application needs PostgreSQL range operators. Keep the field's value shape consistent across every interface that reads or writes it.

Constraints​

Constraints belong inside a field's constraints object:

{
"name": "status",
"type": "string",
"constraints": {
"required": true,
"enum": ["open", "active", "done"]
}
}
ConstraintApplies toEffect
requiredall field typesStores a non-null value
uniquedatabase-compatible field typesPrevents duplicate values
minLengthstringSets the minimum text length
maxLengthstringSets the maximum text length
minimuminteger, numberSets the minimum numeric value
maximuminteger, numberSets the maximum numeric value
enumstringLimits values to the declared list

Constraint failures from the Database API use the structured error shape described in Requests, responses, and errors.

Primary keys​

Declare the key field in fields, then list it in primaryKey:

{
"fields": [
{
"name": "id",
"type": "string",
"format": "uuid",
"constraints": {
"required": true
}
}
],
"primaryKey": ["id"]
}

Use one UUID key named id for new application tables. TaruviBase generates its value when a create omits it; an SDK or REST client can supply a UUID when the application owns record identity.

A schema descriptor can represent more than one primary-key field, and TaruviBase uses that shape for some junction tables. The public record routes address a record through one path value, so this guide does not define composite-key CRUD behavior.

Foreign keys​

Each foreign key names the local field and the referenced table and field:

{
"fields": [
{
"name": "project_id",
"type": "string",
"format": "uuid",
"constraints": {
"required": true
}
}
],
"foreignKeys": [
{
"fields": ["project_id"],
"reference": {
"resource": "projects",
"fields": ["id"]
},
"x-actions": {
"onDelete": "NO ACTION"
}
}
]
}

reference.resource uses the logical table name. Local and referenced field types must be compatible.

onDelete valueResult when the referenced record is deleted
NO ACTIONKeep the reference protected
RESTRICTReject the delete while dependent values exist
CASCADEDelete dependent values
SET NULLClear nullable local fields

TaruviBase defaults to NO ACTION. SET NULL requires nullable local fields.

Test CASCADE with representative data before using it in an important environment.

Schema design conventions​

Use these conventions for schemas that must work consistently across the SDK, REST, Console, and Refine paths:

RequirementPattern
Default valuesGenerate the value in application code and include it in the record payload
Foreign-key deletionChoose NO ACTION, RESTRICT, CASCADE, or SET NULL
Pattern validationValidate the pattern in application code before sending the record
Custom indexingKeep custom index definitions out of application-supplied descriptors; see Plan indexes
Record identityUse the generated UUID id; supply a UUID only when the application owns the identity
Schema changesFollow Plan schema changes

Continue​