Drizzle
TypeScriptのORM
website
github
例
schema定義
code:ts
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
});
export const pets = pgTable('pets', {
id: serial('id').primaryKey(),
name: text('name').notNull(),
ownerId: integer('owner_id').notNull().references(() => users.id),
})
pgTableはPostgreSQL向けのやつ
left join
code:ts
const result = await db.select().from(users).leftJoin(pets, eq(users.id, pets.ownerId))
https://zenn.dev/chimame/articles/60e2824a42fec0#drizzle
Cloudflare D1をサポートしてる
https://zenn.dev/mizchi/articles/d1-drizzle-orm
Claude Code.icon
Drizzle ORMは、TypeScript向けの型安全なORMで、PostgreSQL・MySQL・SQLiteをサポートしています。軽量でサーバーレス環境にも対応し、ゼロ依存で動作します。
drizzle.config.ts
code:typescript
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
dialect: 'postgresql',
schema: './src/db/schema.ts',
out: './drizzle',
dbCredentials: {
url: process.env.DATABASE_URL!,
},
});
2. スキーマ定義
テーブルはTypeScriptのコードとして定義します。DB方言ごとに専用の関数を使います。
code:typescript
// src/db/schema.ts
import { pgTable, serial, text, integer, timestamp, varchar, boolean } from "drizzle-orm/pg-core";
export const users = pgTable('users', {
id: serial('id').primaryKey(),
name: varchar('name', { length: 256 }).notNull(),
email: text('email').notNull(),
age: integer('age'),
isActive: boolean('is_active').default(true),
createdAt: timestamp('created_at').defaultNow(),
});
export const posts = pgTable('posts', {
id: serial('id').primaryKey(),
content: text('content').notNull(),
authorId: integer('author_id').references(() => users.id),
});
ポイント:
pgTable / mysqlTable / sqliteTable で方言を選択
.primaryKey(), .notNull(), .default(), .references() などをチェインして制約を定義
$inferInsert / $inferSelect で型を推論できる
3. DBクライアントの初期化
code:typescript
import { drizzle } from 'drizzle-orm/node-postgres';
import { Pool } from 'pg';
const pool = new Pool({ connectionString: process.env.DATABASE_URL });
const db = drizzle(pool);
4. CRUD操作
すべてSQLライクなメソッドチェインで記述します。
code:typescript
import { eq } from 'drizzle-orm';
import { users } from './schema';
// INSERT
await db.insert(users).values({
name: 'John',
email: 'john@example.com',
age: 30,
});
// SELECT
const allUsers = await db.select().from(users);
const john = await db.select().from(users).where(eq(users.email, 'john@example.com'));
// UPDATE
await db.update(users)
.set({ age: 31 })
.where(eq(users.email, 'john@example.com'));
// DELETE
await db.delete(users).where(eq(users.email, 'john@example.com'));
型推論のヘルパー:
code:typescript
type NewUser = typeof users.$inferInsert; // INSERT用の型
type User = typeof users.$inferSelect; // SELECT結果の型
5. JOIN
SQLのJOINをそのままメソッドチェインで書けます。
code:typescript
import { eq } from 'drizzle-orm';
const result = await db.select()
.from(posts)
.leftJoin(users, eq(posts.authorId, users.id))
.orderBy(posts.id);
6. Relational Queries(リレーショナルクエリ)
JOINを手書きせずに、ネストされたデータを取得できるAPIです。
リレーション定義:
code:typescript
import { defineRelations } from 'drizzle-orm';
import * as schema from './schema';
export const relations = defineRelations(schema, (r) => ({
users: {
posts: r.many.posts(),
},
posts: {
author: r.one.users({
from: r.posts.authorId,
to: r.users.id,
}),
},
}));
クエリ:
code:typescript
// usersと紐づくpostsをネストして取得
const result = await db.query.users.findMany({
with: {
posts: true,
},
});
// => id: 1, name: "Dan", posts: { id: 1, content: "..." }, ... }
7. マイグレーション(drizzle-kit)
drizzle-kitはスキーマの変更をDBに反映するCLIツールです。
table:_
コマンド 用途
drizzle-kit generate スキーマからSQLマイグレーションファイルを生成
drizzle-kit migrate 生成済みマイグレーションをDBに適用
drizzle-kit push マイグレーションファイルなしで直接DBに反映(ローカル開発向き)
drizzle-kit pull 既存DBからスキーマを逆生成
drizzle-kit studio DBを見るGUIを起動
使い分け:
generate + migrate: 本番環境向け。マイグレーション履歴が残る
push: ローカル開発で素早くイテレーションしたいとき
8. Drizzleの特徴まとめ
SQL-likeなAPI: SQLの知識がそのまま活きる。ORMというよりクエリビルダーに近い感覚
完全な型安全: スキーマ定義からSELECT/INSERT/UPDATEすべてで型が推論される
軽量・ゼロ依存: バンドルサイズが小さく、サーバーレス(Cloudflare Workers, Vercel Edge等)に最適
2つのクエリAPI: SQL-likeなクエリビルダーと、Prismaライクなリレーショナルクエリの両方を提供
何か特定の部分をもっと深掘りしたい箇所はありますか?