Guide pratique d'utilisation de Drizzle ORM avec Claude Code
Découvrez guide pratique d'utilisation de Drizzle ORM avec Claude Code. Conseils pratiques et exemples de code inclus.
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の活用法は公式ドキュメントで確認できます。
Summary
Drizzle ORMはSQLに近い記法と軽量さが魅力のORMです。Claude Codeを使えば、型安全なクエリとスキーマ設計を効率的に実装できます。エッジ環境での利用にも適しています。
Related Posts
10 astuces pour tripler votre productivité avec Claude Code
Découvrez 10 astuces pratiques pour tirer le meilleur parti de Claude Code. Des stratégies de prompts aux raccourcis de workflow, ces techniques amélioreront votre efficacité dès aujourd'hui.
Optimisation Canvas/WebGL avec Claude Code
Découvrez l'optimisation Canvas/WebGL avec Claude Code. Conseils pratiques et exemples de code inclus.
Traitement Markdown avec Claude Code
Découvrez traitement Markdown avec Claude Code. Conseils pratiques et exemples de code inclus.