A 실전 가이드 to Using Drizzle ORM: Claude Code 활용 가이드
A practical guide to using drizzle orm: Claude Code 활용 with real-world code examples.
Drizzle ORM とは
Drizzle ORMはTypeScriptファーストの軽量ORMです。SQLに近い記法で타입安全な쿼리を書けるのが特徴です。Claude Code와組み合わせれば、효율적으로데이터베이스層を구축할 수 있습니다。
스키마定義
// db/schema.ts
import {
pgTable,
text,
timestamp,
boolean,
integer,
varchar,
index,
} from "drizzle-orm/pg-core";
import { relations } from "drizzle-orm";
export const users = pgTable("users", {
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
email: varchar("email", { length: 255 }).notNull().unique(),
name: varchar("name", { length: 100 }).notNull(),
avatar: text("avatar"),
createdAt: timestamp("created_at").defaultNow().notNull(),
updatedAt: timestamp("updated_at").defaultNow().notNull(),
}, (table) => ({
emailIdx: index("email_idx").on(table.email),
}));
export const posts = pgTable("posts", {
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
title: varchar("title", { length: 255 }).notNull(),
content: text("content").notNull(),
published: boolean("published").default(false).notNull(),
authorId: text("author_id").notNull().references(() => users.id),
viewCount: integer("view_count").default(0).notNull(),
publishedAt: timestamp("published_at"),
createdAt: timestamp("created_at").defaultNow().notNull(),
}, (table) => ({
authorIdx: index("author_idx").on(table.authorId),
publishedIdx: index("published_idx").on(table.published, table.publishedAt),
}));
export const comments = pgTable("comments", {
id: text("id").primaryKey().$defaultFn(() => crypto.randomUUID()),
content: text("content").notNull(),
authorId: text("author_id").notNull().references(() => users.id),
postId: text("post_id").notNull().references(() => posts.id, { onDelete: "cascade" }),
createdAt: timestamp("created_at").defaultNow().notNull(),
});
リレーション定義
export const usersRelations = relations(users, ({ many, one }) => ({
posts: many(posts),
comments: many(comments),
}));
export const postsRelations = relations(posts, ({ one, many }) => ({
author: one(users, {
fields: [posts.authorId],
references: [users.id],
}),
comments: many(comments),
}));
export const commentsRelations = relations(comments, ({ one }) => ({
author: one(users, {
fields: [comments.authorId],
references: [users.id],
}),
post: one(posts, {
fields: [comments.postId],
references: [posts.id],
}),
}));
쿼리操作
import { drizzle } from "drizzle-orm/node-postgres";
import { eq, and, like, desc, sql, count } from "drizzle-orm";
import * as schema from "./schema";
const db = drizzle(pool, { schema });
// 挿入
async function createPost(data: {
title: string;
content: string;
authorId: string;
}) {
const [post] = await db
.insert(posts)
.values(data)
.returning();
return post;
}
// 검색(페이지네이션付き)
async function getPosts(params: {
page?: number;
perPage?: number;
search?: string;
}) {
const { page = 1, perPage = 20, search } = params;
const conditions = [eq(posts.published, true)];
if (search) {
conditions.push(like(posts.title, `%${search}%`));
}
const [data, [{ total }]] = await Promise.all([
db
.select({
id: posts.id,
title: posts.title,
publishedAt: posts.publishedAt,
authorName: users.name,
commentCount: count(comments.id),
})
.from(posts)
.leftJoin(users, eq(posts.authorId, users.id))
.leftJoin(comments, eq(posts.id, comments.postId))
.where(and(...conditions))
.groupBy(posts.id, users.name)
.orderBy(desc(posts.publishedAt))
.limit(perPage)
.offset((page - 1) * perPage),
db
.select({ total: count() })
.from(posts)
.where(and(...conditions)),
]);
return { data, total, page, perPage };
}
// 업데이트
async function updatePost(id: string, data: Partial<typeof posts.$inferInsert>) {
const [updated] = await db
.update(posts)
.set({ ...data, updatedAt: new Date() })
.where(eq(posts.id, id))
.returning();
return updated;
}
Relational Queries API
// Prismaライクな쿼리
async function getPostWithRelations(id: string) {
return db.query.posts.findFirst({
where: eq(posts.id, id),
with: {
author: {
columns: { id: true, name: true, avatar: true },
},
comments: {
with: {
author: {
columns: { id: true, name: true },
},
},
orderBy: [desc(comments.createdAt)],
limit: 10,
},
},
});
}
마이그레이션
// drizzle.config.ts
import type { Config } from "drizzle-kit";
export default {
schema: "./db/schema.ts",
out: "./drizzle",
dialect: "postgresql",
dbCredentials: {
url: process.env.DATABASE_URL!,
},
} satisfies Config;
# マイグレーション生成
npx drizzle-kit generate
# マイグレーション適用
npx drizzle-kit migrate
# Drizzle Studio(GUI)起動
npx drizzle-kit studio
Prisma との比較
| 特性 | Drizzle | Prisma |
|---|---|---|
| 번들サイズ | 軽量 | やや大きい |
| 쿼리記法 | SQL寄り | 独自API |
| 엣지대응 | 優秀 | 制限あり |
| 스키마定義 | TypeScript | 独自DSL |
| 마이그레이션 | SQL생성 | 自動관리 |
Claude Code로の활용
Drizzle ORMの구현をClaude Code에依頼する例です。Prismaとの比較はPrisma ORM完全가이드、데이터베이스연동에 대해서는Supabase통합개발도 참고하세요.
Drizzle ORMでデータベース層を構築して。
- PostgreSQLのスキーマ定義
- リレーション付きのCRUDクエリ
- ページネーションと検索
- マイグレーション設定
Drizzle ORM의 상세 정보는Drizzle ORM공식 문서를 참고하세요.Claude Code의 활용법은공식 문서에서 확인할 수 있습니다.
정리
Drizzle ORMはSQLに近い記法と軽量さが魅力のORMです。Claude Code를 활용하면 타입安全な쿼리と스키마설계を효율적으로구현할 수 있습니다。엣지環境での利用にも適しています。
#Claude Code
#Drizzle ORM
#database
#TypeScript
#SQL
Related Posts
Tips & Tricks
Tips & Tricks
Claude Code 생산성을 3배로 높이는 10가지 팁
Claude Code를 더 효과적으로 활용하는 10가지 실전 팁을 공개합니다. 프롬프트 전략부터 워크플로 단축키까지, 오늘부터 바로 적용해 보세요.
Tips & Tricks
Tips & Tricks
Canvas/WebGL Optimization: Claude Code 활용 가이드
canvas/webgl optimization: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.
Tips & Tricks
Tips & Tricks
Markdown Implementation: Claude Code 활용 가이드
markdown implementation: Claude Code 활용. 실용적인 팁과 코드 예시를 포함합니다.