drizzle-nextjs-postgres について
Next.js App RouterでDrizzle ORMとPostgreSQLを使う開発者向けのリファレンススキルです。データアクセス、キャッシュ、スキーマ変更、トランザクション、クエリ構築を扱う36のルールを、対象バージョンに沿って提示します。
主な機能
- 017カテゴリ、36のルール
- 02ドライバーと接続プールの指針
- 03Server Componentの読み取りとキャッシュ
- 04Server Actionの更新処理
- 05スキーマ、マイグレーション、トランザクションの指針
- 06PostgreSQLクエリ構築の助言
活用シーン
- 01Drizzleのデータベースモジュールの設定
- 02Server Componentの読み取りキャッシュのレビュー
- 03PostgreSQLスキーマ変更の計画
- 04遅いクエリや接続プール問題の調査
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill drizzle-nextjs-postgresインストール後、Claude Code で/drizzle-nextjs-postgresを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
AGENTS.mdmetadata.jsonassets/templates/_template.mdreferences/_sections.mdconn-disable-prepare-behind-transaction-pooler.mdconn-driver-choice-follows-transactions.mdconn-pass-schema-for-relational-queries.mdconn-pool-sizing-for-serverless.mdconn-server-only-db-module.mdconn-singleton-across-hmr.mdmigrate-add-constraints-not-valid-then-validate.mdmigrate-concurrent-index-outside-transaction.mdmigrate-generate-not-push.mdmigrate-map-renames-explicitly.mdmigrate-run-in-deploy-step-not-at-runtime.mdmut-after-for-post-response-writes.mdmut-authorize-inside-the-action.mdmut-updatetag-vs-revalidatetag.mdquery-count-scans-the-table.mdquery-execute-shape-is-driver-dependent.mdquery-keyset-not-offset.mdquery-not-in-null-trap.mdquery-prepared-statements-need-names.mdrsc-dedupe-with-react-cache.mdrsc-no-request-apis-inside-use-cache.mdrsc-node-runtime-not-edge.mdrsc-suspense-around-uncached-reads.mdrsc-use-cache-is-per-instance-memory.mdrsc-use-cache-replaces-unstable-cache.mdschema-bigint-mode-truncation.md詳細
Next.js での Drizzle + PostgreSQL
Next.js App Router で PostgreSQL 上の Drizzle ORM を使うためのライブラリ参照スキルです。7 カテゴリーにわたる 36 のルールを収録しています。各ルールでは、修正対象となる誤ったデフォルトを示しています。十分な能力を持つモデルがすでに正しく処理できる事項についてのルールはありません。
このスキルは自己完結型です。Postgres + Next.js の開発者に必要なマイグレーションワークフローと型推論のルールも含まれており、基礎となる誤ったデフォルトが Postgres 固有ではない場合も扱います。そのため、作業中に別のスキルを読み込む必要はありません。一部のルールは、姉妹スキルの drizzle-sqlite と意図的に重複しています(同じ誤ったデフォルトを、このコンテキスト向けに再記述しています)。残りは、PostgreSQL の方言であるために存在する、または App Router でコードが実行されるために異なる影響を及ぼす判断事項です。
drizzle-orm 0.45.2、drizzle-kit 0.31.10、Next.js 16.2.11、PostgreSQL 14+ に固定されています。
適用する場面
lib/dbモジュールの作成またはレビュー — ドライバーの選択、プーリング、シングルトン、server-only- Server Component、Route Handler、または
generateMetadataでdb.select()/db.query.*を使ったデータ取得 - キャッシュ対象の決定:
use cache、cacheLife、cacheTag、Reactcache()、またはキャッシュなし - 読み取りパスでキャッシュされた内容を無効化する必要がある、行を変更する Server Action の作成
pgTableの定義または変更 — カラム型、インデックス、列挙型、制約drizzle-kit generate/migrate/pushの実行、または生成された.sqlファイルの手動編集db.transaction()で処理をラップする場合、または競合、デッドロック、プール枯渇のデバッグ- ローカルでは問題ないのに、本番環境では遅いリスト、件数、ページネーションクエリのレビュー
ルールのカテゴリー
| # | カテゴリー | プレフィックス | 対象 |
|---|---|---|---|
| 1 | クライアントの構築とドライバーの選択 | conn- | HMR をまたいだシングルトン、サーバーレスのプールサイズ、プーラー、ドライバーの機能、server-only、schema の受け渡し |
| 2 | Server Component での読み取り | rsc- | Suspense 境界、use cache / cacheLife / cacheTag、リクエストの重複排除、ウォーターフォール、ランタイムの選択 |
| 3 | Server Action とミューテーション | mut- | アクション内での認可とバリデーション、キャッシュの無効化、遅延書き込み |
| 4 | Postgres のスキーマ定義 | schema- | timestamptz、identity カラム、text と varchar、numeric、jsonb、bigint のモード、テーブル設定、列挙型 |
| 5 | マイグレーションとスキーマ変更の安全性 | migrate- | generate と push の違い、同時インデックス作成、マイグレーションの実行場所、名前変更、ロックに配慮した制約 |
| 6 | トランザクションとプールされた接続 | tx- | トランザクション保持による接続コスト、行ロック、シリアライゼーションの再試行 |
| 7 | Postgres のクエリ構築 | query- | キーセットページネーション、件数取得のコスト、ドライバーに依存する execute の形式、NULL のセマンティクス、プリペアドステートメント |
クイックリファレンス
1. クライアントの構築とドライバーの選択
conn-singleton-across-hmr— プールをglobalThisにキャッシュし、開発時のホットリロードによる接続枯渇を防ぎますconn-pool-sizing-for-serverless— 接続の総数はインスタンス数 × 最大数です。max: 1では解決しませんconn-disable-prepare-behind-transaction-pooler— PgBouncer/Supavisor のトランザクションモードではpostgres(url, { prepare: false })を使いますconn-driver-choice-follows-transactions—neon-httpではdb.transactionが例外をスローします。db.batch()は引き続きアトミックです。読み取り後に判断して書き込む処理を基準に選択しますconn-server-only-db-module— スキーマファイルではなく、クライアントモジュールでimport 'server-only'を使いますconn-pass-schema-for-relational-queries—{ schema }を指定しないとdb.queryは空であり、withにはrelations()が必要です
2. サーバーコンポーネントでの読み取り
rsc-suspense-around-uncached-reads— ページの最上部でクエリを実行すると、ルートの静的シェルが失われますrsc-use-cache-replaces-unstable-cache—use cache+cacheLife+cacheTagはunstable_cacheとセグメント設定に取って代わりますrsc-no-request-apis-inside-use-cache—cookies()はuse cache内で例外をスローします。テナント ID は引数として渡してくださいrsc-use-cache-is-per-instance-memory—use cacheはインスタンスごとのメモリ内キャッシュであり、永続的なクエリキャッシュではありませんrsc-dedupe-with-react-cache— React のcache()は、レイアウト、ページ、メタデータ間での検索を重複排除しますrsc-node-runtime-not-edge— Cache Components ではruntime = 'edge'はサポートされていません
3. サーバーアクションとミューテーション
mut-authorize-inside-the-action— アクションは公開 POST エンドポイントです。本文内で認証と入力を確認してくださいmut-updatetag-vs-revalidatetag— 自分の書き込みを読み取る場合はupdateTag、SWR にはrevalidateTag(tag, 'max')を使いますmut-after-for-post-response-writes—after()を使うと、監査と分析の書き込みをレスポンス処理から切り離せます
4. Postgres スキーマ定義
schema-timestamptz-not-timestamp— 単なるtimestamp()は特定の時点を表すものではありませんschema-identity-not-serial—serial()ではなくgeneratedAlwaysAsIdentity()を使いますschema-text-not-varchar-length— 長さ制限が実際のルールでない限り、text()を使いますschema-numeric-is-a-string—numericはstringとして推論されます。金額は整数のセント単位で保存してくださいschema-jsonb-with-dollar-type— インデックス可能にするにはjsonbを、形状を指定するには$type<>()を使いますschema-bigint-mode-truncation—mode: 'number'は 2^53 を超える値を黙って丸めますschema-table-extras-are-an-array— 3 番目のpgTable引数は配列を返します。オブジェクト形式は非推奨ですschema-enum-values-are-append-only— 新しい enum 値は、そのトランザクションがコミットされるまで使用できません
5. マイグレーションとスキーマ変更の安全性
migrate-generate-not-push—pushはレビューされていない差分を適用しますが、generateは内容を確認できるファイルを生成しますmigrate-concurrent-index-outside-transaction—migrate()はすべてのファイルを 1 つのトランザクションで実行するため、その中ではCONCURRENTLYが失敗しますmigrate-run-in-deploy-step-not-at-runtime— コールドスタートが同時に発生するとmigrate()が競合します。トラフィックを受け付ける前に 1 回だけ実行してくださいmigrate-map-renames-explicitly— プロンプトで「列を作成」を選ぶと、名前を変更した列のデータが失われますmigrate-add-constraints-not-valid-then-validate—NOT VALIDはブロッキングスキャンを省略します。2 回目のデプロイで検証してください
6. トランザクションとコネクションプール
tx-no-external-io-inside— トランザクションはコネクションを占有するため、その内部でネットワーク呼び出しを行うとプールが枯渇しますtx-lock-rows-for-read-modify-write—read committedでは、2つのトランザクションが同じ古い行を読み取ることがありますtx-retry-serialization-failures—serializableは SQLSTATE40001で中断し、再試行を想定しています
7. Postgres のクエリ構築
query-keyset-not-offset—OFFSETはスキップするすべての行を読み取って破棄しますquery-count-scans-the-table— Postgres は行数を保存しないため、count(*)は毎回行を走査しますquery-execute-shape-is-driver-dependent— 生のdb.execute()は、node-postgres では.rowsを、postgres-js では配列そのものを返しますquery-not-in-null-trap— サブクエリに NULL が1つでもあると、NOT INは何も返しませんquery-prepared-statements-need-names—.prepare()には名前が必要ですが、トランザクションプーラーを使うとその利点が失われます
使用方法
該当する判断が必要になったら、リファレンスファイルを読んでください。各ルールでは、修正対象となる誤ったデフォルトを示したうえで、標準的な方法を説明します(誤った方法が実際の落とし穴となる場合に限り、誤りと正解を対比します)。
関連スキル
drizzle-sqlite— SQLite 系バックエンドで同じ ORM を使用します。このスキルでは意図的に扱っていない、方言に依存しないクエリ構築ルールを説明しますnextjs— データレイヤー以外の App Router のパターンrelational-database-design— このスキルで宣言方法を学ぶスキーマの選択
リファレンスファイル
| ファイル | 説明 |
|---|---|
| references/_sections.md | カテゴリーの定義と順序 |
| assets/templates/_template.md | 新しいルール用のテンプレート |
| metadata.json | バージョンとソースの参照 |