Edit your schema. Get a safe migration.Edit your schema.Get a safe migration.
Every change to schema.ts becomes a lock-aware migration, a lint report, and fresh types. Typed in TypeScript, with no runtime dependencies.
1/ of 21
schema.ts+1 −0
- ⋯ 9 unchanged lines
- 10
title: t.text().nullable(), - 11
authorId: t.bigint(), - 12+
added: body: t.text().nullable(), - 13
}); - 14
- ⋯ 1 unchanged line
- ⋯ 7 unchanged lines
- 8
const notes = table("notes", { - 9
id: t.identity(), - −
removed: title: t.text().nullable(), - 10+
added: title: t.text(), - 11
authorId: t.bigint(), - 12
}); - ⋯ 2 unchanged lines
- ⋯ 2 unchanged lines
- 3
const authors = table("authors", { - 4
id: t.identity(), - −
removed: name: t.text(), - 5+
added: name: t.text().unique(), - 6
}); - 7
- ⋯ 7 unchanged lines
- ⋯ 8 unchanged lines
- 9
id: t.identity(), - 10
title: t.text().nullable(), - −
removed: authorId: t.bigint(), - 11+
added: authorId: t.bigint().references("authors"), - 12
}); - 13
- ⋯ 1 unchanged line
- −
removed: import { schema, table, t } from "okmodel/pg"; - 1+
added: import { index, schema, table, t } from "okmodel/pg"; - 2
- 3
const authors = table("authors", { - ⋯ 6 unchanged lines
- 10
title: t.text().nullable(), - 11
authorId: t.bigint(), - −
removed: }); - 12+
added: }, { indexes: (columns) => [index(columns.authorId)] }); - 13
- 14
export default schema({ tables: [authors, notes] });
- ⋯ 7 unchanged lines
- 8
const notes = table("notes", { - 9
id: t.identity(), - −
removed: title: t.text().nullable(), - 10+
added: heading: t.text().nullable().renamedFrom("title"), - 11
authorId: t.bigint(), - 12
}); - ⋯ 2 unchanged lines
- ⋯ 9 unchanged lines
- 10
title: t.text().nullable(), - 11
authorId: t.bigint(), - 12+
added: status: t.text().picklist(["draft", "published"]).default("draft"), - 13
}); - 14
- ⋯ 1 unchanged line
- ⋯ 5 unchanged lines
- 6
}); - 7
- −
removed: const notes = table("notes", { - −
removed: id: t.identity(), - −
removed: title: t.text().nullable(), - −
removed: authorId: t.bigint(), - −
removed: }); - −
removed: - −
removed: export default schema({ tables: [authors, notes] }); - 8+
added: export default schema({ tables: [authors] });
$okm generate add_body
planmigrations/0002_add_body.sql · 1 step · expand
- 1
expandadd-columnlock access exclusive
alter table "public"."notes" add column "body" text;
lintclean
no findings, nothing to review
types.okm/types.d.ts · Notes
- 23+
added: readonly body: string | null;
+ 2 more changed lines
planmigrations/0002_require_title.sql · 4 steps · contract
- 1
expandadd-constraintlock access exclusive
alter table "public"."notes" add constraint "notes_title_notnull" check ("title" is not null) not valid; - 2
expandvalidate-constraintlock share update exclusive
alter table "public"."notes" validate constraint "notes_title_notnull"; - 3
contractset-not-nulllock access exclusive
alter table "public"."notes" alter column "title" set not null; - 4
expanddrop-not-null-checklock access exclusive
alter table "public"."notes" drop constraint "notes_title_notnull";
lintclean
no findings, nothing to review
types.okm/types.d.ts · Notes
- −
removed: readonly title: string | null; - 21+
added: readonly title: string;
+ 4 more changed lines
planmigrations/0002_unique_name.sql · 2 steps · expand
- 1
expandcreate-indexlock share update exclusive · outside a transaction
create unique index concurrently "authors_name_key" on "public"."authors" ("name"); - 2
expandadd-constraintlock access exclusive
alter table "public"."authors" add constraint "authors_name_key" unique using index "authors_name_key";
lint1 finding
errorOKM1528step 1: builds a unique or primary key
fix: Deduplicate the rows first. Or allow OKM1528 with a reason.
types
unchanged
planmigrations/0002_link_author.sql · 2 steps · expand
- 1
expandadd-constraintlock access exclusive; share row exclusive on "public"."authors"
alter table "public"."notes" add constraint "notes_authorId_fkey" foreign key ("authorId") references "public"."authors" ("id") not valid; - 2
expandvalidate-constraintlock share update exclusive; row share on "public"."authors"
alter table "public"."notes" validate constraint "notes_authorId_fkey";
lint1 finding
errorOKM1532step 2: validates a foreign key
fix: Add the foreign key NOT VALID, repair the rows, then validate it. Or allow OKM1532 with a reason.
types
unchanged
planmigrations/0002_index_author.sql · 1 step · expand
- 1
expandcreate-indexlock share update exclusive · outside a transaction
create index concurrently "notes_authorId_idx" on "public"."notes" ("authorId");
lintclean
no findings, nothing to review
types
unchanged
planmigrations/0002_rename_title.sql · 1 step · contract
- 1
contractrename-columnlock access exclusive
alter table "public"."notes" rename column "title" to "heading";
lint1 finding
errorOKM1519step 1: renames a column
fix: Add the new column, backfill, and switch readers before dropping the old name. Or allow OKM1519 with a reason.
types.okm/types.d.ts · Notes
- −
removed: readonly title: string | null; - 21+
added: readonly heading: string | null;
+ 4 more changed lines
planmigrations/0002_add_status.sql · 3 steps · expand
- 1
expandadd-columnlock access exclusive
alter table "public"."notes" add column "status" text not null default 'draft'; - 2
expandadd-constraintlock access exclusive
alter table "public"."notes" add constraint "notes_status_check" check ((status IN ('draft', 'published'))) not valid; - 3
expandvalidate-constraintlock share update exclusive
alter table "public"."notes" validate constraint "notes_status_check";
lint1 finding
errorOKM1531step 3: validates a check
fix: Add the check NOT VALID, repair the rows, then validate it. Or allow OKM1531 with a reason.
types.okm/types.d.ts · Notes
- 23+
added: readonly status: "draft" | "published";
+ 2 more changed lines
planmigrations/0002_drop_notes.sql · 1 step · contract
- 1
contractdrop-tablelock access exclusive
drop table "public"."notes";
lint1 finding
errorOKM1511step 1: drops a table
fix: Stop reading the table in an expand migration, then drop it in a later contract. Or allow OKM1511 with a reason.
types.okm/types.d.ts · Notes
- −
removed: export interface Notes { - −
removed: readonly id: string; - −
removed: readonly title: string | null; - −
removed: readonly authorId: string;
+ 19 more changed lines
a nullable column is one expand step, and there is nothing to lintdocs →
PostgreSQL 15–18·Apache-2.0·v0.9.1