Drizzle (Relational)
Purpose
Express the approved relational schema in Drizzle's TypeScript table definitions and use its SQL-proximate query model well — Drizzle is chosen for control and closeness to SQL; this skill keeps that control disciplined. Schema design comes from relational-schema-design.
When to Use
- After Drizzle + a relational DB were approved (
database-selection).
- Not for schema design (upstream) or Prisma/Mongoose projects.
Inputs
- Approved schema design (entities, constraints, types, relations).
- Migration/environment expectations (
database-migrations); hot query paths.
Discovery Questions
- Which dialect helpers/column types map the design (and where are DB-specific features needed — e.g. partial indexes, CHECKs — that Drizzle can express)?
- How will relational reads be written (query builder joins vs the relational query API) per hot path?
- Where do inferred types flow, and where are they mapped to DTOs?
Responsibilities
- Express the design in table definitions: columns/types, FKs with referential actions, unique/composite constraints, CHECKs, indexes (including partial where the design says so) — Drizzle's SQL closeness means little excuse for dropped constraints.
- Own the migration workflow with
database-migrations: drizzle-kit generate producing SQL migrations reviewed like code, applied via the migrator in environments; hand-edited SQL allowed-and-reviewed for what generation misses; drift checked in CI.
- Set query patterns:
- joins written explicitly (that's the point of Drizzle) — relational query API where it stays efficient; hot paths get their SQL shape reviewed;
- selected columns scoped to need; pagination on stable keys;
- prepared statements for hot repeated queries;
db.transaction for multi-write invariants (transactions owns boundaries);
- one pooled client, sized per deployment (
database-performance).
- Keep the boundary clean: inferred row types (
$inferSelect) are data-layer types; map to domain/DTO shapes at the service boundary (../../backend/backend-api-architecture).
- Use
sql template escape hatches parameterized-only (database-security).
Required Workflow
- Translate the design into table definitions; confirm every constraint expressed.
- Wire generate → review → migrate flow + CI drift check.
- Define query patterns per hot path (join shape, select scope, prepared).
- Set transaction and pooling conventions.
- Verify migration SQL matches the design (constraints present, indexes named).
Decision Rules
- Drizzle was chosen for SQL control — exercise it: constraints in-schema, joins explicit, generated SQL read.
- The relational query API is convenience; when its generated SQL disappoints on a hot path, drop to the builder — measured, not assumed (
database-performance).
- Schema TypeScript files are the source; nobody edits the database by hand around them.
- Raw
sql fragments carry parameters, never interpolated strings.
Rules
- Migrations immutable once applied beyond dev (
database-migrations).
- Every table definition change goes through generate + review — no silent drift.
- Type inference doesn't replace DTO mapping at the boundary.
Anti-Patterns
- Treating Drizzle like an ORM black box and never reading its SQL.
- Constraints "handled in app code" that the design assigned to the schema.
select() star-everything on wide tables in list endpoints.
- Interpolating user input into
sql templates.
- Skipping migration review because "it's generated."
Validation Checklist
Definition of Done
The approved schema fully expressed in reviewed Drizzle definitions and migrations, recorded query/transaction/pooling patterns for the hot paths, and a parameterized-only raw-SQL policy — with types flowing cleanly to a mapped boundary.
Related Skills
database-selection, relational-schema-design, database-migrations, transactions, indexing, database-performance, database-security, seed-data, ../../backend/backend-api-architecture.
Related Knowledge
../../../knowledge/ (hot paths, dialect specifics).
Related References
../../../references/database/drizzle/ (patterns, when populated).
Context Loading Guidance
- Requires: approved schema design, migration expectations, hot paths.
- Does not require: re-deciding schema/database, app feature code.
- May load:
database-migrations, database-performance (hot-path review).
- Stop when: expression + workflow + query patterns are recorded.
Token Efficiency Guidance
Reference tables by name against the design doc; show SQL only for contested hot paths. The constraint-coverage checklist is the core artifact.
1---2name: drizzle-relational3description: Use to plan Drizzle over PostgreSQL/MySQL — TypeScript table definitions expressing the approved schema, drizzle-kit migration workflow, SQL-proximate query patterns (joins, prepared statements, transactions), and type flow to the app boundary.4---56# Drizzle (Relational)78## Purpose910Express the approved relational schema in Drizzle's TypeScript table definitions and use its SQL-proximate query model well — Drizzle is chosen for control and closeness to SQL; this skill keeps that control disciplined. Schema *design* comes from `relational-schema-design`.1112## When to Use1314- After Drizzle + a relational DB were approved (`database-selection`).15- **Not** for schema design (upstream) or Prisma/Mongoose projects.1617## Inputs1819- Approved schema design (entities, constraints, types, relations).20- Migration/environment expectations (`database-migrations`); hot query paths.2122## Discovery Questions2324- Which dialect helpers/column types map the design (and where are DB-specific features needed — e.g. partial indexes, CHECKs — that Drizzle *can* express)?25- How will relational reads be written (query builder joins vs the relational query API) per hot path?26- Where do inferred types flow, and where are they mapped to DTOs?2728## Responsibilities2930- Express the design in table definitions: columns/types, FKs with referential actions, unique/composite constraints, CHECKs, indexes (including partial where the design says so) — Drizzle's SQL closeness means little excuse for dropped constraints.31- Own the **migration workflow** with `database-migrations`: `drizzle-kit generate` producing SQL migrations **reviewed like code**, applied via the migrator in environments; hand-edited SQL allowed-and-reviewed for what generation misses; drift checked in CI.32- Set **query patterns**:33 - joins written explicitly (that's the point of Drizzle) — relational query API where it stays efficient; hot paths get their SQL shape reviewed;34 - selected columns scoped to need; pagination on stable keys;35 - prepared statements for hot repeated queries;36 - `db.transaction` for multi-write invariants (`transactions` owns boundaries);37 - one pooled client, sized per deployment (`database-performance`).38- Keep the boundary clean: inferred row types (`$inferSelect`) are data-layer types; map to domain/DTO shapes at the service boundary (`../../backend/backend-api-architecture`).39- Use `sql` template escape hatches parameterized-only (`database-security`).4041## Required Workflow42431. Translate the design into table definitions; confirm every constraint expressed.442. Wire generate → review → migrate flow + CI drift check.453. Define query patterns per hot path (join shape, select scope, prepared).464. Set transaction and pooling conventions.475. Verify migration SQL matches the design (constraints present, indexes named).4849## Decision Rules5051- Drizzle was chosen for SQL control — exercise it: constraints in-schema, joins explicit, generated SQL read.52- The relational query API is convenience; when its generated SQL disappoints on a hot path, drop to the builder — measured, not assumed (`database-performance`).53- Schema TypeScript files are the source; nobody edits the database by hand around them.54- Raw `sql` fragments carry parameters, never interpolated strings.5556## Rules5758- Migrations immutable once applied beyond dev (`database-migrations`).59- Every table definition change goes through generate + review — no silent drift.60- Type inference doesn't replace DTO mapping at the boundary.6162## Anti-Patterns6364- Treating Drizzle like an ORM black box and never reading its SQL.65- Constraints "handled in app code" that the design assigned to the schema.66- `select()` star-everything on wide tables in list endpoints.67- Interpolating user input into `sql` templates.68- Skipping migration review because "it's generated."6970## Validation Checklist7172- [ ] Design fully expressed in table definitions (constraints, indexes, actions).73- [ ] generate → review → migrate flow wired; CI drift check.74- [ ] Hot-path query shapes defined (joins, select scope, prepared).75- [ ] Transactions + pooling conventions set.76- [ ] Raw fragments parameterized-only.77- [ ] Row types mapped to DTOs at the boundary.7879## Definition of Done8081The approved schema fully expressed in reviewed Drizzle definitions and migrations, recorded query/transaction/pooling patterns for the hot paths, and a parameterized-only raw-SQL policy — with types flowing cleanly to a mapped boundary.8283## Related Skills8485`database-selection`, `relational-schema-design`, `database-migrations`, `transactions`, `indexing`, `database-performance`, `database-security`, `seed-data`, `../../backend/backend-api-architecture`.8687## Related Knowledge8889`../../../knowledge/` (hot paths, dialect specifics).9091## Related References9293`../../../references/database/drizzle/` (patterns, when populated).9495## Context Loading Guidance9697- **Requires:** approved schema design, migration expectations, hot paths.98- **Does not require:** re-deciding schema/database, app feature code.99- **May load:** `database-migrations`, `database-performance` (hot-path review).100- **Stop when:** expression + workflow + query patterns are recorded.101102## Token Efficiency Guidance103104Reference tables by name against the design doc; show SQL only for contested hot paths. The constraint-coverage checklist is the core artifact.