Skip to content
NEW

Introducing SurrealDB Studio, the new official app of SurrealDB

Learn more

1/5

Course content preview

8: Computed and asserted fields

Part 5 introduced these field clauses in isolation. Here they land in committed schema files for the planning domain, matching the project planning sample activity table.

As you go through this chapter, add each DEFINE statement to database/schema/activity.surql. You'll apply all of them together with a single surrealkit sync at the end.

Duration shouldn't be stored and maintained by application code when both endpoints already live on the record.

DEFINE FIELD duration ON activity COMPUTED end - start;


COMPUTED fields are evaluated on read (and during projections that need them), not stored at write time. That avoids stale durations when someone updates end without touching a separate column.

SELECT name, start, end, duration FROM activity;


Replace the bare TYPE float line for progress in activity.surql with a constrained range. Don't leave both definitions in the file: SurrealKit treats each DEFINE FIELD as one catalog object keyed by table and field name, so two progress lines produce duplicate metadata and can break a later rollout. Reach for a range ASSERT on numeric bounds, and a literal union when the set is categorical instead (see part 4).

DEFINE FIELD progress ON activity TYPE float ASSERT $value IN 0.0..=1.0;


Invalid writes fail at the field layer:

UPDATE activity:concrete SET progress = 1.5;
-- Field assertion failure


For a custom message, use ASSERT with THROW, as in part 5.

The milestone table uses VALUE time::now() on last_updated in the docs sample. On activity, you might add:

DEFINE FIELD updated_at ON activity VALUE time::now();


VALUE runs on every create and update, which is useful for "last touched" columns. DEFAULT time::now() only fills in missing values on create, unless you add ALWAYS.

Once the three edits above are in activity.surql, apply them with one sync:

surrealkit sync --user root --pass secret --ns main --db main


Existing records pick up COMPUTED duration immediately on the next SELECT. ASSERT only applies to new writes; if legacy data already violates the range, backfill it before you tighten the field (part 3).

On a shared database, changing a field definition is a migration:

  • Local dev: edit activity.surql and sync

  • Staging/production: rollout planstart → deploy → complete (parts 1011)

ALTER FIELD in the shell and editing the .surql file should describe the same end state.

ClauseRole on activity
COMPUTED durationDerived from start / end
ASSERT on progressEnforces 0.0..=1.0
VALUE updated_atOptional audit column


Next: model the dependency graph between activities and projects with RELATION tables.

Previous

7: Activities and seed data

Next lesson

9: Graph dependencies

SurrealDB

The context layer for AI agents.

Documents, graphs, vectors, time-series, and memory.
One transaction, one query, one deployment.

Explore with AI

Stay in the loop

Tutorials, AI agent recipes, and product updates, every two weeks.

Independently verified

SOC 2 Type 2

GDPR

Cyber Essentials Plus

ISO 27001

Trust Centre

Copyright © 2026 SurrealDB Ltd. Registered in England and Wales. Company no. 13615201

Registered address: 3rd Floor 1 Ashley Road, Altrincham, Cheshire, WA14 2DT, United Kingdom

Trading address: Huckletree Oxford Circus, 213 Oxford Street, London, W1D 2LG, United Kingdom