mcpField
A
api-database-drizzle

api-database-drizzle

github.com/agents-incデータ・データベース2678 回インストール2 日前に更新
リポジトリ

api-database-drizzle について

Drizzle ORMとNeonでPostgreSQLアプリを構築するTypeScript開発者向けの実践ガイドです。型安全なスキーマとクエリ、効率的な関連データ取得、トランザクションやマイグレーションの扱いを説明します。

主な機能

  1. 01スキーマ先行の型安全な設計
  2. 02Neon HTTP・WebSocket接続の指針
  3. 03`.with()`によるリレーショナルクエリ
  4. 04トランザクションとマイグレーション
  5. 05Drizzle Kitによるシードの指針

活用シーン

  1. 01サーバーレスアプリの型安全なクエリ作成
  2. 02N+1を避けた関連レコードの取得
  3. 03アトミックなデータ更新
  4. 04スキーマ移行と開発データの管理

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/agents-inc/skills --skill api-database-drizzle

インストール後、Claude Code で/api-database-drizzleを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

metadata.yaml
reference.md
examples/
core.md
migrations.md
queries.md
relations-v2.md
seeding.md
transactions.md

詳細

Drizzle ORM + Neon によるデータベース

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


<critical_requirements>

重要:このスキルを使用する前に

(camelCase の JS を snake_case の SQL にマッピングするため、Drizzle の設定で必ず casing: 'snake_case' を設定してください)

(アトミック性を確保するため、トランザクションのコールバック内では必ず tx パラメーターを使用してください(db は使用しないでください))

(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 接続を必要とするエッジ関数(エッジランタイムではサポートされていません)

主なパターン

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

サーバーレス/エッジとの互換性を確保するため、Drizzle を Neon 用に設定します。主な設定要件:

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"), // Soft delete
  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 を参照してください。


追加のパターン

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

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

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


<red_flags>

重大な注意事項

  • ❌ トランザクション内で tx ではなく db を使用する - トランザクションのコンテキストを迂回し、アトミック性が損なわれます
  • ❌ リレーションで N+1 クエリを発生させる - 1 回のクエリで取得するには .with() を使用してください
  • ❌ casing: 'snake_case' を設定しない - JS と SQL の間でフィールド名が一致しなくなります
  • ❌ v1 のテーブルごとの relations() 構文を使用する - 非推奨です。defineRelations() を使用してください
  • ❌ コールバックベースの where/orderBy を使用する - v1 の構文は非推奨です。オブジェクトベースの構文を使用してください
  • ⚠️ ソフトデリートのチェック(isNull(deletedAt))を含まないクエリ
  • ⚠️ リストクエリにページネーションの上限がない

注意点とエッジケース:

  • Neon HTTP のクエリタイムアウトは 30 秒です。長時間かかるクエリには WebSocket が必要です
  • トランザクションの外部で作成されたプリペアドステートメントは、トランザクション内では使用できません
  • enableRLS() は v1.0.0-beta.1 で非推奨になりました。代わりに pgTable.withRLS() を使用してください
  • バリデーターパッケージは統合されました。drizzle-zod は drizzle-orm/zod になりました(v1 beta 以降)

アンチパターンと注意点の完全な一覧については、reference.md を参照してください。

</red_flags>


<critical_reminders>

重要な注意事項

(camelCase の JS を snake_case の SQL にマッピングするには、Drizzle の設定で casing: 'snake_case' を必ず設定してください)

(アトミック性を確保するには、トランザクションのコールバック内で db ではなく tx パラメーターを必ず使用してください)

(N+1 の問題を避けるには、リレーショナルクエリで .with() を必ず使用してください。すべてのデータを単一の SQL クエリで取得できます)

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

これらのルールに従わないと、フィールド名の不一致、トランザクションのアトミック性の破綻、N+1 によるパフォーマンスの問題が発生し、非推奨の API を使用することになります。

</critical_reminders>

コメント