.prismaファイル)中心、学習コスト高めだが情報量豊富SQLをTypeScriptのオブジェクトとして操作できるようにするライブラリ。生SQL(pgライブラリ)との最大の違いは型安全とマイグレーション管理。
// 生SQL(型なし)
const result = await pool.query('SELECT * FROM users WHERE id = $1', [1]);
const user = result.rows[0]; // any型
// Prisma(型あり)
const user = await prisma.user.findUnique({ where: { id: 1 } });
// User型として自動推論 ✅
💡 ポイント: シンプルなCRUDでは差は小さい。複雑なJOINや動的条件で差が出る
schema.prismaが唯一の真実。そこからマイグレーション・型・Clientが自動生成される。
model User {
id Int @id @default(autoincrement())
email String @unique
posts Post[]
}
npx prisma migrate dev # DBに適用(内部でgenerateも実行)
npx prisma generate # TypeScript型を再生成
💡 ポイント: スキーマ変更 →
migrate devだけで開発中はほぼ完結。マイグレーションはDjangoと同様に差分SQLファイルで管理される
TypeScriptファイルそのままでスキーマ定義。SQLに近い記法でクエリを書く。
// schema.ts
export const users = pgTable('users', {
id: serial('id').primaryKey(),
email: text('email').notNull().unique(),
});
// クエリ(SQLに近い)
const result = await db
.select()
.from(users)
.where(eq(users.id, 1));
💡 ポイント: SQLを知っている人ほど馴染みやすい。generateコマンド不要
| 項目 | Prisma | Drizzle |
|---|---|---|
| スキーマ定義 | 専用DSL(.prisma) | TypeScript(.ts) |
| 学習コスト | 高め | 低め |
| 複雑なクエリ | 苦手 | 得意 |
| バンドルサイズ | 重め | 軽量 |
| Edge Runtime | ❌ | ✅ |
| 情報量 | 豊富 | 急成長中 |
💡 ポイント: SQL経験あり・Vercel Edge使いたい・Supabase小中規模 → Drizzleが有利
Supabase Client → RLS有効 ✅(フロントや認証済みAPI)
Drizzle直接接続 → RLSバイパス ⚠️ → サーバーサイド限定で使う
// drizzle.config.ts
export default defineConfig({
schema: './src/schema.ts',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!, // SupabaseのDB接続文字列
},
});
💡 ポイント: HonoのAPIルート内でDrizzleを使うのがMickeyのスタックに最もフィット
| ミス | 改善策 |
|---|---|
| スキーマ変更後にgenerateを忘れる | migrate devは内部でgenerateも実行するので開発中は不要 |
| DrizzleをフロントでRLS前提で使う | Drizzle直接接続はRLSをバイパスするのでサーバーサイド限定 |
| Prismaが重いからと敬遠しすぎる | チームにSQL不慣れなメンバーがいる場合はPrismaが適切 |
| DrizzleのクエリをSQL知識なしで書こうとする | SQLの基礎を先に固めると学習コストが大幅に下がる |
- ORMの真価はシンプルなCRUDより複雑なJOIN・動的クエリで発揮される
- PrismaのマイグレーションはDjangoと同様に差分ファイル管理(中身がPythonではなくSQL)
- Drizzleのスキーマは普通のTSファイルなのでエディタ補完がそのまま効く
- Supabase + Drizzleの役割分担:認証・シンプルなCRUDはSupabase Client、複雑なクエリはDrizzle