From harness-claude
Defines Drizzle ORM relations using relations(), one(), many(), references() for one-to-one, one-to-many, many-to-many, self-relations, and relational queries with TypeScript type inference.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Define Drizzle relations with relations(), one(), many(), references(), and inferred types
Guides Drizzle ORM type-safe schema design, relational queries, prepared statements, migrations, and transactions. Use for database schema, queries, migrations, and performance optimization in TypeScript.
Provides production expertise on Drizzle ORM for TypeScript schema design, migrations, relations, relational queries, and edge/serverless deployments.
Defines type-safe database schemas, queries, relations, and migrations using Drizzle ORM in TypeScript for PostgreSQL, MySQL, SQLite, Cloudflare D1, and Durable Objects.
Share bugs, ideas, or general feedback.
Define Drizzle relations with relations(), one(), many(), references(), and inferred types
with clauses to load related dataimport { relations } from 'drizzle-orm';
import { users, posts } from './schema';
export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
}));
one() on both sides:export const usersRelations = relations(users, ({ one }) => ({
profile: one(profiles, {
fields: [users.id],
references: [profiles.userId],
}),
}));
export const profilesRelations = relations(profiles, ({ one }) => ({
user: one(users, {
fields: [profiles.userId],
references: [users.id],
}),
}));
many() on the parent, one() with fields/references on the child:export const usersRelations = relations(users, ({ many }) => ({
posts: many(posts),
}));
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
}));
export const postsRelations = relations(posts, ({ many }) => ({
postTags: many(postTags),
}));
export const tagsRelations = relations(tags, ({ many }) => ({
postTags: many(postTags),
}));
export const postTagsRelations = relations(postTags, ({ one }) => ({
post: one(posts, { fields: [postTags.postId], references: [posts.id] }),
tag: one(tags, { fields: [postTags.tagId], references: [tags.id] }),
}));
const usersWithPosts = await db.query.users.findMany({
with: {
posts: {
limit: 10,
orderBy: (posts, { desc }) => [desc(posts.createdAt)],
with: { tags: true },
},
},
});
export const employeesRelations = relations(employees, ({ one, many }) => ({
manager: one(employees, {
fields: [employees.managerId],
references: [employees.id],
relationName: 'managerReports',
}),
reports: many(employees, { relationName: 'managerReports' }),
}));
import * as schema from './schema';
const db = drizzle(pool, { schema });
// db.query.users.findMany({ with: { posts: true } }) now works
Drizzle has two query APIs: the SQL-like query builder (db.select().from(users)) and the relational query API (db.query.users.findMany()). Relations only affect the relational query API. The SQL-like builder uses explicit join() calls instead.
Relations are not foreign keys. Defining relations() does not create database constraints. Foreign keys are defined on the schema columns with .references(). Relations are a query-time concept for the ORM to know how to join tables.
Type inference with relations:
type UserWithPosts = Awaited<
ReturnType<
typeof db.query.users.findFirst<{
with: { posts: true };
}>
>
>;
Or extract with InferSelectModel and manually add the relation types.
Multiple relations to the same table: Use relationName to disambiguate:
export const postsRelations = relations(posts, ({ one }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
relationName: 'postAuthor',
}),
editor: one(users, {
fields: [posts.editorId],
references: [users.id],
relationName: 'postEditor',
}),
}));
Trade-offs:
https://orm.drizzle.team/docs/relations