mcpField
A
api-database-vercel-postgres

api-database-vercel-postgres

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

api-database-vercel-postgres について

非推奨となった `@vercel/postgres` を使うプロジェクトの保守と移行向けのコーディングスキルです。接続プールや直接接続、クエリ、エッジランタイムの注意点を扱い、新規プロジェクトには `@neondatabase/serverless` を推奨します。

主な機能

  1. 01`sql` によるパラメーター化クエリ
  2. 02複数クエリのセッションとトランザクション
  3. 03カスタムプールとクライアントの設定
  4. 04プール接続と直接接続の使い分け
  5. 05エッジランタイムの接続パターン
  6. 06`@neondatabase/serverless` への移行ガイド

活用シーン

  1. 01既存の `@vercel/postgres` アプリの保守
  2. 02Vercel のエッジまたはサーバーレス関数での DB クエリ
  3. 03同一セッションで複数のクエリを実行
  4. 04アプリを `@neondatabase/serverless` に移行

インストール

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

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

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

同梱ファイル

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

metadata.yaml
reference.md
examples/
core.md

詳細

Vercel Postgres のパターン

クイックガイド: @vercel/postgres は @neondatabase/serverless を薄くラップしたもので、POSTGRES_URL 環境変数から自動的に接続します。単発のクエリには sql タグ付きテンプレートを使用します(エッジに対応し、自動でプールされます)。複数のクエリを実行する場合は、sql.connect() を使用してクライアントを取得します。エッジランタイムでは、リクエスト間で接続を再利用できません(maxUses: 1)。このパッケージは非推奨です(2024年12月)。新しいプロジェクトでは、@neondatabase/serverless を直接使用してください。


<critical_requirements>

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

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

(単発のクエリには、必ず sql タグ付きテンプレートを使用してください。POSTGRES_URL から自動的に接続し、プーリングを処理します)

(sql.connect() または pool.connect() で取得したクライアントを使用した後は、必ず client.release() を呼び出してください。クライアントがリークすると、接続プールが枯渇します)

(プール接続には必ず POSTGRES_URL を、直接接続には POSTGRES_URL_NON_POOLING を使用してください。これらを混在させると、接続の枯渇や機能の制限が発生します)

(@vercel/postgres は非推奨であることを必ず明記し、新しいプロジェクトには @neondatabase/serverless を推奨してください)

</critical_requirements>


自動検出: @vercel/postgres、vercel postgres、POSTGRES_URL、POSTGRES_URL_NON_POOLING、sql tagged template vercel、createPool vercel、createClient vercel、VercelPool、VercelClient

使用する場面:

  • すでに @vercel/postgres を使用している既存プロジェクトの保守
  • Vercel のエッジ/サーバーレス関数から Postgres にクエリを実行する場合
  • 環境変数から自動接続する、シンプルなデータベースアクセス
  • @vercel/postgres から @neondatabase/serverless への移行

対象となる主なパターン:

  • sql タグ付きテンプレート(自動プーリング、エッジ対応、単発のクエリ)
  • 複数のクエリを実行するクライアントセッション用の sql.connect()
  • カスタム設定用の createPool() / createClient()
  • 環境変数(POSTGRES_URL、POSTGRES_URL_NON_POOLING)
  • エッジランタイムと Node.js ランタイムの違い
  • @neondatabase/serverless への移行方法

使用しない場面:

  • 新しいプロジェクト(@neondatabase/serverless を直接使用してください)
  • 接続を維持する長時間稼働のサーバープロセス(標準の pg ドライバーを使用してください)
  • 一般的な PostgreSQL クエリ構文(SQL/Postgres のスキルを使用してください)

詳細なリソース:

  • 判断フレームワークと早見表については、reference.md を参照してください

例:

  • examples/core.md -- sql タグ付きテンプレート、createPool、createClient、エッジのパターン、移行

## 設計方針

@vercel/postgres は、Vercel にデプロイされたアプリケーションの接続管理を簡素化する @neondatabase/serverless の便利なラッパーです。POSTGRES_URL/POSTGRES_URL_NON_POOLING 環境変数(Vercel Marketplace 連携によって自動的にプロビジョニングされます)から接続文字列を読み取るため、接続文字列を手動で作成する必要はありません。

基本原則:

  1. 設定不要の接続 -- sql エクスポートは環境変数から自動接続します。コード内で接続文字列を設定する必要はありません。
  2. タグ付きテンプレートの安全性 -- sql は関数ではなく、タグ付きテンプレートリテラルです。パラメーターは自動的にパラメーター化され、SQL インジェクションを防ぎます。
  3. デフォルトでコネクションプーリング -- sql と createPool() はプール済み接続文字列(POSTGRES_URL)を使用します。createClient() は直接接続文字列(POSTGRES_URL_NON_POOLING)を使用します。
  4. エッジ環境への対応 -- エッジランタイムでは、IO 接続がリクエスト間で維持できないため、SDK は maxUses: 1 を設定します。1 つのリクエスト内で複数のクエリを実行するには、sql.connect() を使用します。

非推奨化の背景:

Vercel Postgres は 2024 年 12 月にサービスを終了しました。すべてのデータベースは Neon に移行されました。npm パッケージ @vercel/postgres(v0.10.0)はメンテナンスされていません。移行先:

  • 全面的な移行(推奨): @neondatabase/serverless(現在も開発が続いており、HTTP トランザクションや合成可能なフラグメントを備えた、より豊富な API を提供)

基本パターン

パターン 1:sql による単発クエリ

sql エクスポートは POSTGRES_URL から自動接続するタグ付きテンプレートです。値は自動的にパラメーター化され、SQL インジェクションを防ぎます。適切な例と不適切な例を比較した詳しいサンプルについては、examples/core.md を参照してください。

import { sql } from "@vercel/postgres";

const ACTIVE_STATUS = "active";
const { rows } =
  await sql`SELECT id, name FROM users WHERE status = ${ACTIVE_STATUS}`;

パターン 2:sql.connect() による複数クエリのセッション

同じ接続で複数のクエリを実行する必要がある場合(トランザクションや順次処理など)は、クライアントを取得します。単独の sql 呼び出しごとに異なるプール接続が使われる可能性があるため、別々の sql 呼び出しで BEGIN/COMMIT を実行しても、実際のトランザクションにはなりません。トランザクションのパターンについては、examples/core.md を参照してください。

const client = await sql.connect();
try {
  await client.sql`BEGIN`;
  // ... queries on same client ...
  await client.sql`COMMIT`;
} catch (error) {
  await client.sql`ROLLBACK`;
  throw error;
} finally {
  client.release();
}

パターン 3:カスタムプールとクライアント

カスタム接続文字列(セカンダリデータベース)には createPool() を使用します。マイグレーションやセッションレベルの機能で必要となる直接接続(非プール接続)には createClient() を使用します。詳しいサンプルについては、examples/core.md を参照してください。

import { createPool } from "@vercel/postgres";
const pool = createPool({
  connectionString: process.env.SECONDARY_POSTGRES_URL,
});
const { rows } =
  await pool.sql`SELECT id, title FROM posts WHERE published = true`;

パターン 4:エッジランタイムに関する考慮事項

エッジランタイムでは、接続をリクエスト間で再利用できないため、SDK は maxUses: 1 を設定します。単一の sql 呼び出しは問題なく動作しますが、複数のクエリを実行する場合は、1 つの接続を共有するために sql.connect() を使用します。エッジ固有のパターンについては、examples/core.md を参照してください。


パターン 5:@neondatabase/serverless への移行

@vercel/postgres は非推奨のため、@neondatabase/serverless に移行してください。詳しい移行例については、examples/core.md を参照してください。

把握しておくべき主な違い:

  • @vercel/postgres は { rows, rowCount, ... } を返します。一方、@neondatabase/serverless の neon() は行を直接返します(fullResults: true の場合を除く)。
  • @vercel/postgres は POSTGRES_URL を読み取ります。一方、@neondatabase/serverless では接続文字列(通常は DATABASE_URL)を明示的に指定する必要があります。
  • @neondatabase/serverless は、sql.transaction() による HTTP トランザクションと、合成可能なフラグメントを追加します。

<decision_framework>

選択の指針

使用する API
What kind of operation?
+-- Single query (SELECT, INSERT, UPDATE, DELETE)
|   +-- Use sql tagged template directly
+-- Multiple queries that must be atomic (transaction)?
|   +-- Use sql.connect() to get a client, wrap in BEGIN/COMMIT
+-- Need custom connection string (not POSTGRES_URL)?
|   +-- Use createPool() with explicit connectionString
+-- Need session-level features (SET, LISTEN/NOTIFY)?
|   +-- Use createClient() (reads POSTGRES_URL_NON_POOLING)
+-- Starting a new project?
    +-- Use @neondatabase/serverless instead
環境変数の選択
What is the workload?
+-- Serverless/edge function --> POSTGRES_URL (pooled)
+-- Application queries --> POSTGRES_URL (pooled)
+-- Schema migrations --> POSTGRES_URL_NON_POOLING (direct)
+-- LISTEN/NOTIFY --> POSTGRES_URL_NON_POOLING (direct)
+-- pg_dump / pg_restore --> POSTGRES_URL_NON_POOLING (direct)

</decision_framework>


<red_flags>

注意すべき重大な問題

優先度の高い問題:

  • sql.connect() を使わずに sql でトランザクションを実行する — sql タグ付きテンプレートの呼び出しごとに、異なるプール接続が使われる可能性があります。ある接続で BEGIN を実行し、別の接続で COMMIT を実行しても、トランザクションはまったく成立しません。
  • sql.connect() の後に client.release() を呼び忘れる — クライアントがリークすると接続プールが使い尽くされ、その後のすべてのクエリがタイムアウトするまでハングします。
  • マイグレーションに POSTGRES_URL を使う — プール接続はトランザクションモードの PgBouncer 経由で実行されるため、マイグレーションツールに必要なセッションレベルの機能が使えなくなります。

優先度が中程度の問題:

  • タグ付きテンプレートの代わりに文字列補間を使う — sql`...${value}...` は安全です。sql.query(\...${value}...`)` は SQL インジェクションにつながります。
  • プールやクライアントを閉じずに作成する — createClient() では明示的な client.end() が必要です。呼び忘れると接続がリークします。
  • 非推奨であることを無視する — @vercel/postgres v0.10.0 が最後のバージョンです。セキュリティパッチやバグ修正はリリースされません。

注意点とエッジケース:

  • エッジランタイムの maxUses: 1 — エッジでは、プールは1つのリクエスト内で接続を再利用できません。複数の sql 呼び出しを実行すると、それぞれで新しい接続が開かれます。1つの接続を共有するには sql.connect() を使ってください。
  • sql は関数ではなくタグ付きテンプレートです — sql(...) は誤りです。sql`...` が正しい書き方です。Vercel 以外の Postgres の例からコピーする際によくある間違いです。
  • POSTGRES_URL と DATABASE_URL の違い — @vercel/postgres はデフォルトで POSTGRES_URL を読み取ります。@neondatabase/serverless はデフォルトでは何も読み取らないため、明示的に渡してください。Neon への移行後、Vercel は両方を設定しますが、コードでは SDK の想定に合わせる必要があります。
  • PgBouncer のトランザクションモードの制限 — プール接続経由では、SET/RESET、LISTEN/NOTIFY、PRESERVE 付きの一時テーブル、セッションレベルのアドバイザリロックは使用できません。
  • @neondatabase/serverless とは結果の形式が異なる — @vercel/postgres は { rows, rowCount, fields } を返します。Neon の neon() 関数は行を直接返します。この違いを考慮しないと、移行中にコードが動作しなくなります。

</red_flags>


<critical_reminders>

重要な注意事項

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

(単発のクエリには必ず sql タグ付きテンプレートを使ってください。POSTGRES_URL から自動接続し、接続プールを処理します)

(sql.connect() または pool.connect() で取得したクライアントを使用した後は、必ず client.release() を呼び出してください。クライアントがリークすると接続プールが使い尽くされます)

(プール接続には必ず POSTGRES_URL を、直接接続には POSTGRES_URL_NON_POOLING を使ってください。これらを混在させると、接続枯渇や機能制限が発生します)

(@vercel/postgres が非推奨であることを明記してください。新規プロジェクトには @neondatabase/serverless を推奨してください)

これらのルールに従わないと、接続プールの枯渇、SQL インジェクションの脆弱性、または気付かれないトランザクション失敗が発生します。

</critical_reminders>

コメント