Skip to main content

Migrations and SQL

The CLI exposes explicit database lifecycle commands. The canonical migration command is kura migration up.

Migration files​

A migration filename must have the shape <timestamp>_<name>.sql. For example:

supabase/migrations/202609100001_create_posts.sql

Each file is one SQL unit. The gateway applies it atomically and records the version only after the transaction completes.

pnpm kura migration up --dir supabase/migrations

After kura start, the CLI obtains its local admin URL and generated dev-server key from Compose status without printing either credential. For a remote gateway, supply --url URL and KURA_DEV_SERVER_KEY (or legacy KURA_SECRET_KEY) in the trusted shell. The runner does not accept a wallet private key, execute shell from migration contents, or accept a secret key as a CLI flag.

To explicitly give a trusted local server its own service credential, use pnpm kura key dev. It prints KURA_DEV_SERVER_KEY=… only for that direct request; status, metadata, Dashboard storage, and the browser bundle exclude it. See dev-server keys.

EXECUTION ON CHAIN function migrations use the same command, but require a fresh V2 instance. See on-chain SQL functions for the bounded profile and the deliberate no-side-door data rule.

User-defined enum types​

Declare a named enum before the tables or functions which use it. Its labels are catalog metadata, so the declaration replays with the rest of the migration on a new gateway.

supabase/migrations/202609100002_post_state.sql
CREATE TYPE post_state AS ENUM ('draft', 'published', 'archived');

CREATE TABLE posts (
id bigint PRIMARY KEY,
state post_state NOT NULL DEFAULT 'draft'
);

Enum values are not untyped text: Kura validates writes and SQL function arguments/returns against the declared labels. Equality, inequality, IN, and literal casts are supported. Label changes, declaration-order comparisons, and ORDER BY are deliberately rejected until their full PostgreSQL semantics can be implemented deterministically.

Query SQL​

pnpm kura db query --file scripts/check-posts.sql

Or pass one command directly:

pnpm kura db query --query 'select count(*) from posts'

Manage the local stack​

pnpm kura start
pnpm kura status
pnpm kura logs gateway
pnpm kura stop

If startup fails with service "bootstrap" didn't complete successfully: exit 1, first run pnpm kura logs bootstrap. In particular, Recorded Kurabase contract no longer exists means the saved local instance references a contract absent from Anvil's persisted state. Recorded Kurabase contract predates Dashboard wallet management means the local contract needs explicit redeployment for Dashboard administration. Do not remove individual local volumes to work around this. When the local stack is disposable, pnpm kura db reset --yes removes the complete local chain, instance and signer volumes, then a subsequent pnpm kura start deploys a fresh instance. This is destructive: back up any local data you need first.

There is no legacy kura migrate alias. Keeping one canonical command prevents scripts from quietly drifting between incompatible command forms.