PAYATHON 2026

Prisma db push 使用 Supabase 事务池时卡住,如何配置连接?

数据小许

建议让 npx prisma db push 使用 Supabase 的直连地址,适合使用连接池的应用查询可以继续使用事务池地址。你已经观察到直连成功、事务池卡住,可以先这样恢复数据库结构同步。

Prisma Client 可以配合 Supabase transaction pooler 使用,但应用查询和数据库结构管理对连接的要求不同。Prisma 官方给出的配置方式是:应用运行时使用池化连接,Prisma CLI 的 db push、迁移等操作单独配置直连地址。Prisma 连接池配置说明

为什么显示数据库信息后仍然卡住?

原始日志停在:

Datasource "db": PostgreSQL database "postgres", schema "public" at "...pooler.supabase.com:6543"

这行日志只说明 CLI 已读取并显示数据源配置,不能据此认定后续数据库操作、权限检查或结构同步已经成功。

Supabase 事务池在每个事务结束后归还底层数据库连接,跨事务的会话状态无法持续保留;共享事务池也不支持 prepared statements。数据库结构管理工具可能依赖持续的连接和会话行为,因此需要与普通应用查询分别配置。Supabase 事务模式限制

直连成功而事务池卡住,应优先检查连接模式及其兼容性。不过,现有日志没有显示具体卡在哪里,无法断定此次一定是 prepared statements、锁等待或某个特定版本缺陷导致的。

先确认 5432 对应的是哪种连接

Supabase 的直连和 Session pooler 都可能使用 5432,需要同时检查主机名和连接模式:

连接方式地址特征主要用途
Direct connectiondb.[PROJECT-REF].supabase.co:5432数据库管理、迁移及适合直连的常驻后端
Session pooler[POOLER-HOST]:5432需要持续会话、但直连网络不可达时的替代连接
Transaction pooler[POOLER-HOST]:6543Serverless 等存在大量短连接的应用查询

从 Supabase Dashboard 的 Connect 面板复制对应的连接串。不要只把 6543 改成 5432 就认为已经切换为直连,因为主机名和用户名也可能不同。Supabase 连接方式说明

如果开发机或 CI 只有 IPv4,而项目的直连地址仅支持 IPv6,可以使用 Session pooler 作为替代。具体以项目 Connect 面板显示的网络支持为准。

按 Prisma 版本配置 CLI 和应用连接

先确认版本:

npx prisma -v

问题没有提供版本,请根据项目版本选择以下 Prisma 6 常见配置或 Prisma 7 配置。

Prisma 6:在 schema.prisma 中使用 directUrl

对于使用传统 Prisma 查询引擎并在 schema.prisma 中管理连接的 Prisma 6 项目,可以保留两个环境变量:

DATABASE_URL="postgresql://postgres.[PROJECT-REF]:[ENCODED-PASSWORD]@[POOLER-HOST]:6543/postgres?sslmode=require&pgbouncer=true"
DIRECT_URL="postgresql://postgres:[ENCODED-PASSWORD]@db.[PROJECT-REF].supabase.co:5432/postgres?sslmode=require"

修改 prisma/schema.prisma 的数据源配置:

datasource db {
  provider  = "postgresql"
  url       = env("DATABASE_URL")
  directUrl = env("DIRECT_URL")
}

url 用于应用查询,directUrl 用于需要绕过事务池的 CLI 操作。这是 Prisma 6 支持的配置方式。Prisma 6 数据源配置参考

示例中的 pgbouncer=true 用于传统 Prisma 查询引擎与共享事务池的兼容配置。不要把它当作解决 db push 卡住的通用开关,结构同步仍应使用 DIRECT_URL。

方括号中的内容都需要替换为实际值;密码中的保留字符需要进行 URL 编码,池化地址与直连地址应分别从控制台复制。

Prisma 7:在 prisma.config.ts 中设置 CLI 地址

Prisma 7 使用 prisma.config.ts 配置 CLI 连接,不再沿用上面的 directUrl 配置方式。将直连地址放进 datasource.url。Prisma 7 升级说明

原始日志显示环境变量放在 prisma/.env。如果继续保留这个位置,可以在项目根目录的 prisma.config.ts 中明确加载:

import { config } from "dotenv";
import { defineConfig, env } from "prisma/config";

config({ path: "prisma/.env" });

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: env("DIRECT_URL"),
  },
});

这个示例假设从项目根目录运行命令,并已安装 dotenv。如果环境变量由部署平台注入,则不必依赖该文件。

应用运行时再通过 driver adapter 单独读取 DATABASE_URL。Prisma 7 的底层驱动配置与传统查询引擎不同,prepared statements 和连接池参数应按实际使用的 adapter 和 driver 配置,不要假定旧的 URL 参数会控制所有驱动行为。

修改后如何确认生效?

停止正在等待的命令,然后重新执行:

npx prisma db push

检查 CLI 显示的数据源是否已指向预期的直连主机,或你明确选择的 Session pooler。如果仍然显示事务池地址,先检查 CLI 实际加载的配置文件,以及 shell、CI 或部署平台中是否存在覆盖文件值的环境变量。

命令成功结束后,检查 Supabase 中目标 schema 的表结构。原问题使用的是 public,注意检查这个 schema。

如果改为正确的直连后仍然卡住,再排查网络可达性、数据库账号权限、阻塞会话及锁等待。当前材料不足以确认这些因素中的任何一个就是根因。

开发环境和生产环境怎么选?

连接方式主要取决于操作类型和部署形态:

场景建议
开发阶段快速验证 schema使用直连执行 prisma db push
开发阶段维护可发布的结构变更使用直连执行 prisma migrate dev,保存迁移文件
生产环境部署已有迁移在部署流程中通过直连执行 prisma migrate deploy
Serverless 或大量短连接的应用运行时使用 Transaction pooler,并处理驱动兼容性
常驻 Node.js 后端根据网络、连接预算和实例数量选择直连或池化连接

db push 不生成迁移文件,也不记录完整的结构变更历史,适合用于开发原型。需要把结构变更部署到测试、生产环境时,应采用迁移流程。Prisma 对 db push 的适用范围说明

如果使用 migrate dev,还要留意其 shadow database 要求;这是开发迁移的单独配置问题。对于已经有数据、但尚未建立迁移历史的数据库,应先规划迁移基线,避免直接触发重置。

备注:内容仅供参考。