一键导入
kysely
Kysely database queries. Use when writing, reviewing, or debugging Kysely selects, mutations, joins, transactions, filters, or aggregates.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Kysely database queries. Use when writing, reviewing, or debugging Kysely selects, mutations, joins, transactions, filters, or aggregates.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Skill writing principles. Use when creating, editing, or reviewing any SKILL.md.
Skill rule extraction and creation. Use when the user says /learn.
Frontend components and Tailwind. Use when creating, reviewing, refactoring, splitting, or organizing React components, shared components, component folders, or Tailwind classes.
TanStack Query in React. Use when implementing or reviewing queries, mutations, invalidation, or query hooks.
Lint and optimize existing skills. Use when the user says /skill-linter.
Implement the agreed slice. Use when the user invokes $execute-slice or wants to implement a slice agreed via slice-prd.
| name | kysely |
| description | Kysely database queries. Use when writing, reviewing, or debugging Kysely selects, mutations, joins, transactions, filters, or aggregates. |
Use this skill for any Kysely query: selects, mutations, joins, transactions, filters, aggregates, or query review.
DbUsers, usually one file per table/domain.jsonArrayFrom for related data. Do not fetch rows, build a Map, and stitch results by hand.executeTakeFirst() read contracts return an envelope like { data }; do not publish T | undefined or convert absence to null.sql is for expressions the builder cannot express, never whole queries..set() / .values() fields directly. undefined means absent; null means SQL NULL..execute() for mutations when you do not need returned values. Use .returning() only when the returned row matters..values() into a single-use variable. Inline the mutation input; use .returning() for values confirmed by the DB.The pg driver returns bigint, numeric, and decimal as strings. int and integer return numbers. Cast counts and numeric expressions in SQL when the result should be a number:
eb.cast<number>(eb.fn.countAll(), "int4").as("count");
If an expression is already declared as sql<number>, trust that type and do not call Number() afterward.
Use database schema types as the source of truth:
| Situation | Use | Do not use |
|---|---|---|
| Fixed values | CREATE TYPE status AS ENUM (...) | VARCHAR with a manual TS union |
| Typed arrays | text[], integer[] | jsonb |
| Fixed JSON structure | Separate columns | jsonb |
Use typed jsonb only for dynamic structures, discriminated unions, or config objects that are genuinely stored as one blob. Override generated types with interface extends Omit<...> and ColumnType; import DB from the override file, not the generated file.
Prefer expression-builder APIs when Kysely can express the query. Raw sql is for expressions the builder cannot express, not whole queries.
eb.fn.coalesce(...) instead of raw coalesce(...) when the builder can express it.eb.cast<T>(...) for casts. eb.cast accepts string references directly; do not wrap them in eb.ref().eb.exists(...) for relation existence checks. Do not use count(*) > 0.export const DbItems = {
async listByUserId(user_id: number, filters: ItemFilters) {
let query = db.selectFrom("items as i").where("i.user_id", "=", user_id);
if (filters.category_id) {
query = query.where("i.category_id", "=", filters.category_id);
}
const data = await query.selectAll("i").execute();
return { data };
},
async getById(id: number) {
const data = await db
.selectFrom("items as i")
.where("i.id", "=", id)
.selectAll("i")
.executeTakeFirst();
return { data };
},
};
| Situation | Use |
|---|---|
| Parent with children | jsonArrayFrom in one query |
| Need fields from another table | JOIN, not fetch + Map |
| Conditional selected columns | .$if() |
| Conditional WHERE | normal if that reassigns query |
| Boolean "does relation exist?" | eb.exists() |
| WHERE narrowed nullable column | $narrowType before .execute() |
| Multiple filtered aggregates over same base | CTE + scalar subselects |
| N updates with different row values | INSERT ... ON CONFLICT ... DO UPDATE |
Read the reference that matches the query before writing or judging it:
references/joins.md when related rows, joins, parent/children shapes, or fetch-plus-merge code appears.references/expression-builder.md when aggregates, coalesce, cast, exists, or raw SQL appears.references/postgres.md when runtime numeric types, enum schema choices, arrays, or typed jsonb appears.references/mutations.md when insert/update/delete code, optional fields, read envelopes, ownership predicates, batch upsert, .$if, or $narrowType appears.BATCH-UPDATE.md when many rows need different update values.