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. 02在 Vercel 边缘或无服务器函数中查询数据库
  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 技能)

详细资源:

示例:

  • examples/core.md —— sql 标签模板、createPool、createClient、边缘模式、迁移

## 设计理念

@vercel/postgres 是对 @neondatabase/serverless 的便捷封装,可简化 Vercel 部署应用的连接管理。它会从 POSTGRES_URL / POSTGRES_URL_NON_POOLING 环境变量读取连接字符串(由 Vercel Marketplace 集成自动配置),因此你无需手动构造连接字符串。

核心原则:

  1. 零配置连接 -- sql 导出项会根据环境变量自动连接。无需在代码中设置连接字符串。
  2. 带标签模板的安全性 -- sql 是带标签的模板字面量,而非函数。参数会自动参数化,从而防止 SQL 注入。
  3. 默认使用连接池 -- sql 和 createPool() 使用连接池连接字符串(POSTGRES_URL)。createClient() 使用直连字符串(POSTGRES_URL_NON_POOLING)。
  4. 适配边缘运行时 -- 在边缘运行时中,SDK 会设置 maxUses: 1,因为 IO 连接无法在请求之间保持。若要在单个请求中执行多个查询,请使用 sql.connect()。

弃用背景:

Vercel Postgres 于 2024 年 12 月停止服务。所有数据库均已迁移至 Neon。@vercel/postgres npm 包(v0.10.0)已不再维护。迁移路径:

  • 完整迁移(推荐): @neondatabase/serverless(积极开发中,API 更丰富,支持 HTTP 事务和可组合片段)

核心模式

模式 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 调用可正常运行;若要执行多个查询,请使用 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 处理事务,却没有使用 sql.connect()——每次调用 sql 标记模板都可能使用不同的连接池连接。在一个连接上执行 BEGIN,在另一个连接上执行 COMMIT,意味着事务根本没有生效。
  • 使用 sql.connect() 后忘记调用 client.release()——泄漏的客户端会耗尽连接池,导致后续所有查询一直挂起,直到超时。
  • 将 POSTGRES_URL 用于迁移——池化连接会通过事务模式的 PgBouncer 运行,这会导致迁移工具所需的会话级功能失效。

中优先级问题:

  • 使用字符串插值而非标记模板——sql`...${value}...` 是安全的。sql.query(\...${value}...`)` 会导致 SQL 注入。
  • 创建池或客户端后不关闭——createClient() 需要显式调用 client.end()。忘记调用会导致连接泄漏。
  • 忽略弃用信息——@vercel/postgres v0.10.0 是最后一个版本,不会再发布安全补丁或错误修复。

易踩坑点和边缘情况:

  • Edge 运行时中的 maxUses: 1——在 Edge 上,连接池无法在一次请求中重用连接。如果连续发起多次 sql 调用,每次都会新建一个连接。使用 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>

评论

支持 Markdown