jpskill.com
🛠️ 開発・MCP コミュニティ

api-database-drizzle

Drizzle ORMを使ってデータベースのクエリ実行や移行作業を効率化し、アプリケーション開発におけるデータ操作をスムーズにするSkill。

📜 元の英語説明(参考)

Drizzle ORM, queries, migrations

🇯🇵 日本人クリエイター向け解説

一言でいうと

Drizzle ORMを使ってデータベースのクエリ実行や移行作業を効率化し、アプリケーション開発におけるデータ操作をスムーズにするSkill。

※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o api-database-drizzle.zip https://jpskill.com/download/10232.zip && unzip -o api-database-drizzle.zip && rm api-database-drizzle.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/10232.zip -OutFile "$d\api-database-drizzle.zip"; Expand-Archive "$d\api-database-drizzle.zip" -DestinationPath $d -Force; ri "$d\api-database-drizzle.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して api-database-drizzle.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → api-database-drizzle フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
1

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

Drizzle ORM + Neon を使用したデータベース

クイックガイド: 型安全なクエリには Drizzle ORM を、エッジ互換の接続には Neon serverless Postgres を使用します。自動 TypeScript 型を使用したスキーマファースト設計。defineRelations() とオブジェクトベースの where 構文で RQB v2 を使用します。.with() を使用したリレーショナルクエリは、N+1 問題を回避します。アトミックな操作にはトランザクションを使用します。


<critical_requirements>

重要: この Skill を使用する前に

すべてのコードは、CLAUDE.md のプロジェクト規約に従う必要があります (kebab-case、名前付きエクスポート、インポート順序、import type、名前付き定数)

(camelCase JS を snake_case SQL にマップするには、Drizzle 設定で casing: 'snake_case' を必ず設定する必要があります)

(アトミック性を保証するには、トランザクションコールバック内で db ではなく tx パラメータを必ず使用する必要があります)

(N+1 問題を回避するには、リレーショナルクエリに .with() を必ず使用する必要があります - 単一の SQL クエリですべてのデータをフェッチします)

(RQB v2 には defineRelations() を必ず使用してください - 古いテーブルごとの relations() 構文は非推奨です)

</critical_requirements>


詳細なリソース:

  • コード例については、examples/ フォルダを参照してください。
    • core.md - 接続設定とスキーマ定義 (常にロードされます)
    • queries.md - リレーショナルクエリとクエリビルダー
    • relations-v2.md - defineRelations() を使用した RQB v2 (NEW)
    • transactions.md - アトミックな操作
    • migrations.md - Drizzle Kit ワークフロー
    • seeding.md - 開発データの投入 (drizzle-seed を含む)
  • 意思決定フレームワークとアンチパターンについては、reference.md を参照してください。

自動検出: drizzle-orm, @neondatabase/serverless, neon-http, db.query, db.transaction, drizzle-kit, pgTable, defineRelations, drizzle-seed

使用する場合:

  • 型安全なデータベースクエリを必要とするサーバーレス関数
  • マイグレーションを使用したスキーマファースト開発
  • API ルートを使用したサーバーレンダリングアプリの構築

使用しない場合:

  • フレームワークのサーバーアクションを直接使用するシンプルなアプリ (オーバーヘッドが正当化されない)
  • 従来の TCP 接続プーリングのみを必要とするアプリ (標準の Postgres クライアントを使用)
  • TypeScript 以外のプロジェクト (型安全性の主な利点を失う)
  • WebSocket 接続を必要とするエッジ関数 (エッジランタイムではサポートされていません)

<patterns>

コアパターン

パターン 1: データベース接続 (Neon HTTP)

サーバーレス/エッジ互換性のために Neon で Drizzle を構成します。主な設定要件:

export const db = drizzle(sql, {
  schema,
  casing: "snake_case", // Maps camelCase JS to snake_case SQL
});
  • 使用前に DATABASE_URL を検証します (存在しない場合は例外をスローします)
  • フィールド名の不一致を防ぐために、常に casing: "snake_case" を設定します
  • HTTP (エッジ互換) には neon() を、WebSocket (長いクエリ) には Pool を使用します

完全な接続設定、WebSocket 構成、および Drizzle Kit 構成は、examples/core.md にあります。


パターン 2: スキーマ定義

Drizzle のスキーマビルダーを使用して、TypeScript 型でテーブルを定義します。

export const companies = pgTable("companies", {
  id: uuid("id").primaryKey().defaultRandom(),
  name: varchar("name", { length: 255 }).notNull(),
  slug: varchar("slug", { length: 255 }).unique(),
  deletedAt: timestamp("deleted_at"), // ソフトデリート
  createdAt: timestamp("created_at").defaultNow(),
});
  • varchar の代わりに、制約された値には pgEnum() を使用します
  • 常に createdAt/updatedAt タイムスタンプを含めます
  • ソフトデリートには deletedAt を追加します
  • 孤立したレコードを防ぐために、外部キーに onDelete: "cascade" を設定します
  • プライマリキーには uuid().defaultRandom() または integer().generatedAlwaysAsIdentity() を使用します

完全なスキーマの例 (enum、リレーション、ジャンクションテーブル、identity カラム) は、examples/core.md にあります。


パターン 3: .with() を使用したリレーショナルクエリ

.with() を使用して、単一の SQL クエリで関連データを効率的にフェッチします。

const job = await db.query.jobs.findFirst({
  where: and(eq(jobs.id, jobId), isNull(jobs.deletedAt)),
  with: {
    company: { with: { locations: true } },
    jobSkills: { with: { skill: true } },
  },
});
// Result is fully typed: job.company.name, job.jobSkills[0].skill.name
  • 関連データをフェッチする場合は、.with() を使用して db.query を使用します -- 単一の SQL クエリ、N+1 なし
  • カスタムカラムの選択、複雑な JOIN、集計には、クエリビルダー (db.select()) を使用します
  • ソフトデリートされたテーブルの場合は、常に WHERE 条件に isNull(deletedAt) を含めます

完全なリレーショナルクエリの例、N+1 アンチパターン、および動的なフィルタリングは、examples/queries.md にあります。

</patterns>


追加のパターン

次のパターンは、examples/ に完全な例とともに記載されています。

  • クエリビルダー - 複雑なフィルター、動的な条件、カスタム JOIN - queries.md を参照してください
  • トランザクション - アトミックな操作、エラー処理、ロールバック - transactions.md を参照してください
  • データベースマイグレーション - Drizzle Kit ワークフロー、generate vs push - migrations.md を参照してください
  • データベースシーディング - 開発データ、安全なクリーンアップ - seeding.md を参照してください

パフォーマンスの最適化 (インデックス、プリペアドステートメント、ページネーション) は、reference.md に記載されています。


<red_flags>

RED FLAGS

  • トランザクション内で tx の代わりに db を使用する - トランザクションコンテキストをバイパスし、アトミック性を損なう
  • リレーションを使用した N+1 クエリ - .with() を使用して 1 つのクエリでフェッチする
  • casing: 'snake_case' を設定しない - JS と SQL の間のフィールド名の不一致
  • v1 relations() テーブルごとの構文を使用する - 非推奨、defineRelations() を使用する
  • コールバックベースの where/orderBy を使用する - v1 構文は非推奨、オブジェクトベースの構文を使用する
  • ⚠️ ソフトデリートチェック (isNull(deletedAt)) がないクエリ
  • ⚠️ リストクエリにページネーション制限がない

注意点とエッジケース:

  • Neon HTTP には 30 秒のクエリタイムアウトがあります - 長いクエリには WebSocket が必要です
  • Prepar

(原文がここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Database with Drizzle ORM + Neon

Quick Guide: Use Drizzle ORM for type-safe queries, Neon serverless Postgres for edge-compatible connections. Schema-first design with automatic TypeScript types. Use RQB v2 with defineRelations() and object-based where syntax. Relational queries with .with() avoid N+1 problems. Use transactions for atomic operations.


<critical_requirements>

CRITICAL: Before Using This Skill

All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering, import type, named constants)

(You MUST set casing: 'snake_case' in Drizzle config to map camelCase JS to snake_case SQL)

(You MUST use tx parameter (NOT db) inside transaction callbacks to ensure atomicity)

(You MUST use .with() for relational queries to avoid N+1 problems - fetches all data in single SQL query)

(You MUST use defineRelations() for RQB v2 - the old relations() per-table syntax is deprecated)

</critical_requirements>


Detailed Resources:


Auto-detection: drizzle-orm, @neondatabase/serverless, neon-http, db.query, db.transaction, drizzle-kit, pgTable, defineRelations, drizzle-seed

When to use:

  • Serverless functions needing type-safe database queries
  • Schema-first development with migrations
  • Building server-rendered apps with API routes

When NOT to use:

  • Simple apps using framework server actions directly (overhead not justified)
  • Apps needing traditional TCP connection pooling only (use standard Postgres clients)
  • Non-TypeScript projects (lose primary benefit of type safety)
  • Edge functions requiring WebSocket connections (not supported in edge runtime)

<patterns>

Core Patterns

Pattern 1: Database Connection (Neon HTTP)

Configure Drizzle with Neon for serverless/edge compatibility. Key setup requirements:

export const db = drizzle(sql, {
  schema,
  casing: "snake_case", // Maps camelCase JS to snake_case SQL
});
  • Validate DATABASE_URL before use (throw on missing)
  • Always set casing: "snake_case" to prevent field name mismatches
  • Use neon() for HTTP (edge-compatible) or Pool for WebSocket (long queries)

Full connection setup, WebSocket config, and Drizzle Kit config in examples/core.md.


Pattern 2: Schema Definition

Define tables with TypeScript types using Drizzle's schema builder:

export const companies = pgTable("companies", {
  id: uuid("id").primaryKey().defaultRandom(),
  name: varchar("name", { length: 255 }).notNull(),
  slug: varchar("slug", { length: 255 }).unique(),
  deletedAt: timestamp("deleted_at"), // Soft delete
  createdAt: timestamp("created_at").defaultNow(),
});
  • Use pgEnum() for constrained values instead of varchar
  • Always include createdAt/updatedAt timestamps
  • Add deletedAt for soft deletes
  • Set onDelete: "cascade" on foreign keys to prevent orphaned records
  • Use uuid().defaultRandom() or integer().generatedAlwaysAsIdentity() for primary keys

Full schema examples (enums, relations, junction tables, identity columns) in examples/core.md.


Pattern 3: Relational Queries with .with()

Fetch related data efficiently in a single SQL query using .with():

const job = await db.query.jobs.findFirst({
  where: and(eq(jobs.id, jobId), isNull(jobs.deletedAt)),
  with: {
    company: { with: { locations: true } },
    jobSkills: { with: { skill: true } },
  },
});
// Result is fully typed: job.company.name, job.jobSkills[0].skill.name
  • Use db.query with .with() when fetching related data -- single SQL query, no N+1
  • Use query builder (db.select()) for custom column selection, complex JOINs, aggregations
  • Always include isNull(deletedAt) in WHERE conditions for soft-deleted tables

Full relational query examples, N+1 anti-patterns, and dynamic filtering in examples/queries.md.

</patterns>


Additional Patterns

The following patterns are documented with full examples in examples/:

  • Query Builder - Complex filters, dynamic conditions, custom JOINs - see queries.md
  • Transactions - Atomic operations, error handling, rollback - see transactions.md
  • Database Migrations - Drizzle Kit workflow, generate vs push - see migrations.md
  • Database Seeding - Development data, safe cleanup - see seeding.md

Performance optimization (indexes, prepared statements, pagination) is documented in reference.md.


<red_flags>

RED FLAGS

  • Using db instead of tx inside transactions - Bypasses transaction context, breaking atomicity
  • N+1 queries with relations - Use .with() to fetch in one query
  • Not setting casing: 'snake_case' - Field name mismatches between JS and SQL
  • Using v1 relations() per-table syntax - Deprecated, use defineRelations()
  • Using callback-based where/orderBy - v1 syntax deprecated, use object-based syntax
  • ⚠️ Queries without soft delete checks (isNull(deletedAt))
  • ⚠️ No pagination limits on list queries

Gotchas & Edge Cases:

  • Neon HTTP has 30-second query timeout - long queries need WebSocket
  • Prepared statements created outside transactions cannot be used inside transactions
  • enableRLS() deprecated in v1.0.0-beta.1 - use pgTable.withRLS() instead
  • Validator packages consolidated: drizzle-zod is now drizzle-orm/zod (since v1 beta)

For the complete list of anti-patterns and gotchas, see reference.md.

</red_flags>


<critical_reminders>

CRITICAL REMINDERS

All code must follow project conventions in CLAUDE.md

(You MUST set casing: 'snake_case' in Drizzle config to map camelCase JS to snake_case SQL)

(You MUST use tx parameter (NOT db) inside transaction callbacks to ensure atomicity)

(You MUST use .with() for relational queries to avoid N+1 problems - fetches all data in single SQL query)

(You MUST use defineRelations() for RQB v2 - the old relations() per-table syntax is deprecated)

Failure to follow these rules will cause field name mismatches, break transaction atomicity, create N+1 performance issues, and use deprecated APIs.

</critical_reminders>