> ## Documentation Index
> Fetch the complete documentation index at: https://private-7c7dfe99-vortex-format.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 在 Cloudflare Workers 中使用 ClickHouse Managed Postgres

> 通过 Hyperdrive 从 Cloudflare Worker 查询 ClickHouse Managed Postgres，内容涵盖 node-postgres、TLS 证书验证、本地开发以及部署到 workers.dev

export const BetaBadge = ({link, galaxyTrack, galaxyEvent}) => {
  if (link) {
    return <a href={link} target="_blank" rel="noopener noreferrer" className="betaBadge" onClick={galaxyTrack && galaxyEvent ? galaxyOnClick(galaxyEvent) : undefined}>
                <span>Beta</span>
            </a>;
  }
  return <a href="https://clickhouse.com/docs/reference/settings/beta-and-experimental-features#beta-features" className="betaBadge">
            <span>Beta 版功能</span>
        </a>;
};

<BetaBadge link="https://clickhouse.com/cloud/postgres" galaxyTrack={true} galaxyEvent="docs.managed-postgres.guides-cloudflare-workers-beta" />

[Cloudflare Workers](https://developers.cloudflare.com/workers/) 在 Cloudflare 的网络上运行您的代码，而 [Hyperdrive](https://developers.cloudflare.com/hyperdrive/) 会维护一个从该网络到您数据库的连接池，这样每个请求都无需重新进行 TCP 和 TLS 握手。在本指南中，您将创建一个会验证实例证书的 Hyperdrive 配置，构建一个使用 [`node-postgres`](https://node-postgres.com/) (`pg`) 写入和读取行的 TypeScript Worker，通过 `wrangler dev` 在本地运行，并将其部署到 `workers.dev`。

<h2 id="prerequisites">
  前置条件
</h2>

* 一个 [Cloudflare 账户](https://dash.cloudflare.com/sign-up)。Workers 免费版和付费版套餐均可使用 Hyperdrive。
* [Node.js](https://nodejs.org/) 20 或更高版本。本指南已在 Node.js 24.21.0、Wrangler 4.145.0、`create-cloudflare` 2.73.1、`pg` 8.23.1 和 Postgres 18 环境下测试通过。
* 一个 ClickHouse Cloud 账户。
* [`psql`](https://www.postgresql.org/download/)，用于创建数据库和表。您也可以在 [SQL 控制台](/zh/integrations/connectors/sql-clients/sql-console)中运行这些 SQL 语句。

<h2 id="create-service">
  创建 ClickHouse Managed Postgres 服务
</h2>

在 ClickHouse Cloud 控制台中，点击 **New service**，然后选择 **Postgres**。实例会在几分钟内准备就绪。完整操作步骤请参阅[快速入门](/zh/products/managed-postgres/quickstart)。

<h2 id="connection-details">
  获取连接详细信息
</h2>

在服务的左侧边栏中点击 **Connect**。保持选中 **Directly**，并开启 **Use SSL**。此时 URL 会以 `sslmode=verify-full&sslrootcert=<service-name>-ca-certificate.pem` 结尾。点击 **Download CA certificate** 下载实例的 CA 证书。也可以在 **Settings → CA Certificate** 中下载。

本指南让 Hyperdrive 使用端口 `5432` 上的**直接**连接，而不是端口 `6432` 上内置的 PgBouncer：

* Hyperdrive 本身就是一个以事务模式运行的连接池器。它会与数据库维持少量长连接，并在所有 Worker 请求之间共享这些连接，而这原本正是 PgBouncer 的职责。Cloudflare 建议为 Hyperdrive 配置直接连接字符串，而非经过连接池的连接字符串。
* 让 Hyperdrive 连接端口 `6432` 同样可行，但串联两个事务模式连接池会多一次网络跳转，还多出一处需要调优连接池大小的地方，却无法提升容量。
* 在 Workers Free 计划下，每个 Hyperdrive 配置最多打开约 20 个连接；在 Paid 计划下约为 100 个，均在默认 `max_connections` (500) 的范围之内。如果同一实例上还有多个 Hyperdrive 配置或其他客户端，请将它们的连接数累加计算，必要时在 [Settings](/zh/products/managed-postgres/settings) 中调整 `max_connections`，或在 Hyperdrive 中调整源端连接数上限。

<Note>
  如果使用了 [IP 访问列表](/zh/products/managed-postgres/security)，由于 Hyperdrive 从 [Cloudflare 的 IP 地址范围](https://www.cloudflare.com/ips/)发起连接，必须将这些地址范围加入允许列表。
</Note>

<h2 id="create-database">
  创建数据库
</h2>

将下载的证书重命名为 `ca-certificate.pem`，然后创建一个数据库和一张 `notes` 表。将 `<PASSWORD>` 和主机地址替换为 **Connect** 对话框中提供的值：

```bash theme={null}
psql "postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/postgres?sslmode=verify-full&sslrootcert=ca-certificate.pem" -c "CREATE DATABASE guide_cloudflare;"
```

```bash theme={null}
psql "postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_cloudflare?sslmode=verify-full&sslrootcert=ca-certificate.pem" -c "CREATE TABLE notes (id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY, content text NOT NULL, created_at timestamptz NOT NULL DEFAULT now());"
```

```text theme={null}
CREATE TABLE
```

<h2 id="create-project">
  创建 Worker 项目
</h2>

使用 `create-cloudflare` 基于 "Hello World" 模板创建一个 TypeScript Worker，然后安装 `pg`：

```bash theme={null}
npm create cloudflare@latest -- hyperdrive-notes --type=hello-world --lang=ts --no-deploy
cd hyperdrive-notes
npm install pg
npm install -D @types/pg
```

<Tip>
  **要集成到现有应用中？**

  可跳过 `npm create cloudflare`。在您的 Worker 项目中运行 `npm install pg` 和 `npm install -D @types/pg`，然后继续完成[创建 Hyperdrive 配置](#create-hyperdrive) (此步骤会添加 Hyperdrive 绑定) 和[配置 Worker](#configure-worker) (此步骤会启用 `nodejs_compat`) 。
</Tip>

将 `ca-certificate.pem` 移至项目目录中。如果您之前未使用过 Wrangler，请运行 `npx wrangler login`，通过您的 Cloudflare 账户为其授权。

<h2 id="create-hyperdrive">
  创建 Hyperdrive 配置
</h2>

Hyperdrive 始终会加密与数据库之间的连接，但默认情况下不会使用实例的 CA 来校验证书。若要实现与 `sslmode=verify-full` 等效的效果，请先将 CA 证书上传到您的 Cloudflare 账户：

```bash theme={null}
npx wrangler cert upload certificate-authority --ca-cert ca-certificate.pem --name managed-postgres-ca
```

```text theme={null}
Success! Uploaded CA Certificate managed-postgres-ca
ID: <CA_CERTIFICATE_ID>
```

使用输出中的 `ID` 创建 Hyperdrive 配置。连接字符串使用端口 `5432` 和 `guide_cloudflare` 数据库，不包含任何 SSL 参数；TLS 改为通过 `--sslmode` 和 `--ca-certificate-id` 配置：

```bash theme={null}
npx wrangler hyperdrive create managed-postgres \
  --connection-string="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_cloudflare" \
  --ca-certificate-id <CA_CERTIFICATE_ID> \
  --sslmode verify-full \
  --caching-disabled \
  --binding HYPERDRIVE \
  --update-config
```

```text theme={null}
✅ Created new Hyperdrive PostgreSQL config: <HYPERDRIVE_ID>
```

Hyperdrive 在创建配置时会连接到您的数据库。使用 `--sslmode verify-full` 时，它会检查服务器证书是否由您上传的 CA 签名，以及证书是否与主机名匹配。只要有一项检查未通过，命令就会失败并报错 (例如 `cert verification failed - unable to get local issuer certificate`) ，且不会创建任何配置。密码保存在您 Cloudflare 账户下的 Hyperdrive 配置中，而不是保存在您的项目里。

`--binding HYPERDRIVE --update-config` 会将该配置添加到 `wrangler.jsonc` 中，使您的 Worker 可以通过 `env.HYPERDRIVE` 访问它。如果您的项目使用的是 `wrangler.toml`，Wrangler 不会修改该文件；此时请将命令输出的 `[[hyperdrive]]` 代码片段手动粘贴到该文件中。

<Tip>
  **查询缓存**

  Hyperdrive 可以缓存读查询的结果，默认缓存时长为 60 秒。本指南使用 `--caching-disabled` 关闭了缓存，以确保写入后立即读取能返回新写入的行。对于读密集且可以容忍结果略有滞后的查询，您可以另外创建一个启用缓存的配置，并同时绑定这两个配置。请参阅[查询缓存](https://developers.cloudflare.com/hyperdrive/concepts/query-caching/)。
</Tip>

<h2 id="configure-worker">
  配置 Worker
</h2>

`pg` 依赖 Node.js 兼容层。打开 `wrangler.jsonc`，在 `compatibility_date` 旁添加 `nodejs_compat` 标志。修改后，文件的相关部分如下所示：

```jsonc title="wrangler.jsonc" theme={null}
{
	"name": "hyperdrive-notes",
	"main": "src/index.ts",
	"compatibility_date": "2026-09-26",
	"compatibility_flags": ["nodejs_compat"],
	"hyperdrive": [
		{
			"binding": "HYPERDRIVE",
			"id": "<HYPERDRIVE_ID>"
		}
	]
}
```

如果使用的是 `wrangler.toml` 文件，则应改为在 `compatibility_date` 下方添加 `compatibility_flags = ["nodejs_compat"]`。如果该文件中已有 `compatibility_flags`，请将 `nodejs_compat` 添加到该列表中。

重新生成 TypeScript 类型，使 `env.HYPERDRIVE` 具有明确的类型：

```bash theme={null}
npx wrangler types
```

如果您的项目仍在使用 `@cloudflare/workers-types` 包，运行 `wrangler types` 时会输出说明，指导您如何改用生成的类型。

<h2 id="query">
  查询数据库
</h2>

将 `src/index.ts` 替换为一个 Worker：它在收到 `POST /notes` 请求时创建一条笔记，在收到 `GET /notes` 请求时列出所有笔记。如果使用的是现有 Worker，则改为在 `fetch` 处理程序中添加相同的 `/notes` 处理逻辑：

```ts title="src/index.ts" theme={null}
import { Client } from "pg";

export default {
	async fetch(request, env, ctx): Promise<Response> {
		const url = new URL(request.url);
		if (url.pathname !== "/notes") {
			return new Response("Not found", { status: 404 });
		}

		// Hyperdrive keeps the connections to Postgres, so a new client per request is cheap.
		const client = new Client({ connectionString: env.HYPERDRIVE.connectionString });
		await client.connect();

		try {
			if (request.method === "POST") {
				// Create
				const { content } = await request.json<{ content: string }>();
				const { rows } = await client.query(
					"INSERT INTO notes (content) VALUES ($1) RETURNING id, content, created_at",
					[content],
				);
				return Response.json(rows[0], { status: 201 });
			}

			// Read
			const { rows } = await client.query("SELECT id, content, created_at FROM notes ORDER BY id");
			return Response.json(rows);
		} finally {
			// Close the client after the response is sent.
			ctx.waitUntil(client.end());
		}
	},
} satisfies ExportedHandler<Env>;
```

`env.HYPERDRIVE.connectionString` 指向的是 Hyperdrive，而不是您的实例。Worker 与 Hyperdrive 之间的链路完全位于 Cloudflare 内部，因此无需配置 SSL 参数。到 Postgres 的 TLS 连接 (含证书验证) 由 Hyperdrive 负责处理。

<Note>
  Hyperdrive 以事务模式运行，与 PgBouncer 类似：每个事务都可能使用不同的 Postgres 连接。`pg` 的参数化查询、事务以及命名预处理语句均可正常使用。请勿在多个查询之间依赖会话状态 (例如会话级别的 `SET`) ，而应在事务内改用 `SET LOCAL`。
</Note>

<h2 id="local-development">
  在本地运行
</h2>

`wrangler dev` 会在您的本机上运行 Worker。在本地运行时，Hyperdrive 不会对连接进行池化，binding 会直接连接到 `CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_<BINDING>` 中指定的数据库。请将该变量设置为直连的连接字符串，并在其中包含 `sslmode=verify-full` 和 CA 证书的路径，然后启动 Worker：

```bash theme={null}
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgresql://postgres:<PASSWORD>@your-instance.pg.clickhouse.cloud:5432/guide_cloudflare?sslmode=verify-full&sslrootcert=ca-certificate.pem"
npx wrangler dev --port 3108
```

```text theme={null}
Found a non-empty CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE variable for binding. Hyperdrive will connect to this database during local development.
...
Ready on http://localhost:3108
```

Wrangler 会为本地连接处理 TLS。`sslrootcert` 的路径相对于你运行 `wrangler dev` 时所在的目录进行解析。

<Warning>
  如果省略 `sslmode`，本地连接将**不会加密**。使用 `sslmode=require` 时，连接会加密，但不会验证证书。请始终将 `sslmode=verify-full` 与 `sslrootcert` 搭配使用。如果 CA 缺失或不正确，请求会失败并报错 `Connection terminated unexpectedly`。
</Warning>

在另一个终端中创建一条笔记：

```bash theme={null}
curl -X POST http://localhost:3108/notes -H "Content-Type: application/json" -d '{"content": "Hello from wrangler dev"}'
```

```json theme={null}
{"id":"1","content":"Hello from wrangler dev","created_at":"2026-09-30T16:58:16.232Z"}
```

列出所有笔记：

```bash theme={null}
curl http://localhost:3108/notes
```

```json theme={null}
[{"id":"1","content":"Hello from wrangler dev","created_at":"2026-09-30T16:58:16.232Z"}]
```

`pg` 会将 `bigint` 列以字符串形式返回，因此 `id` 的值是 `"1"`，而不是 `1`。

<h2 id="deploy">
  部署
</h2>

部署工作线程：

```bash theme={null}
npx wrangler deploy
```

```text theme={null}
Your Worker has access to the following bindings:
Binding                                   Resource
env.HYPERDRIVE (<HYPERDRIVE_ID>)          Hyperdrive Config

Uploaded hyperdrive-notes (2.35 sec)
Deployed hyperdrive-notes triggers (0.76 sec)
  https://hyperdrive-notes.<your-subdomain>.workers.dev
```

如果这是您的第一个 Worker，Wrangler 会提示您注册一个 `workers.dev` 子域名。通过已部署的 Worker 创建一条笔记：

```bash theme={null}
curl -X POST https://hyperdrive-notes.<your-subdomain>.workers.dev/notes -H "Content-Type: application/json" -d '{"content": "Hello from Hyperdrive"}'
```

```json theme={null}
{"id":"2","content":"Hello from Hyperdrive","created_at":"2026-09-30T16:58:39.733Z"}
```

在浏览器中打开 `https://hyperdrive-notes.<your-subdomain>.workers.dev/notes`，即可看到这两条笔记。返回的响应如下所示：

```json theme={null}
[{"id":"1","content":"Hello from wrangler dev","created_at":"2026-09-30T16:58:16.232Z"},{"id":"2","content":"Hello from Hyperdrive","created_at":"2026-09-30T16:58:39.733Z"}]
```

<h2 id="verify">
  在控制台中验证
</h2>

在服务的左侧边栏中打开 **SQL 控制台**，依次展开 `guide_cloudflare` 和 `public`，然后点击 `notes` 表，即可看到这两条笔记：

| id | content | created\_at |
| - | - | - |
| 1 | Hello from wrangler dev | 2026-09-30 16:58:16.232466+00 |
| 2 | Hello from Hyperdrive | 2026-09-30 16:58:39.733203+00 |

<h2 id="clean-up">
  清理
</h2>

如需清理你在 Cloudflare 账户中创建的资源，请删除 Worker、Hyperdrive 配置以及 CA 证书：

```bash theme={null}
npx wrangler delete
npx wrangler hyperdrive delete <HYPERDRIVE_ID>
npx wrangler cert delete --name managed-postgres-ca
```

如果 `wrangler cert delete` 提示 `Certificate cannot be deleted while in use`，请在删除 Hyperdrive 配置后等待一分钟，再重新运行该命令。

<h2 id="next-steps">
  后续步骤
</h2>

* [连接](/zh/products/managed-postgres/connection)：连接字符串、PgBouncer 和 TLS
* [设置](/zh/products/managed-postgres/settings)：Postgres 参数，例如 `max_connections`
* [只读副本](/zh/products/managed-postgres/read-replicas)：扩展读取流量处理能力
* [Hyperdrive 文档](https://developers.cloudflare.com/hyperdrive/)：查询缓存、连接池调优和可观测性
