使用Prisma+Google Cloud SQL PostgreSQL在Cloud Run中无法找到表
Schema.prisma 代码片段
generator client { provider = "prisma-client-js" previewFeatures = ["driverAdapters"] } datasource db { provider = "postgresql" url = env("DATABASE_URL") }
数据库信息
- 数据库名称:core-db
- PostgreSQL版本:15
环境详情
开发环境
使用以下连接URL可成功构建Schema并执行迁移,本地运行时能正常查看core-db中的所有实体:
postgresql://postgres:{password}@{public_ip}:5432/core-db
生产环境
部署至Google Cloud Run时采用以下连接URL配置:
postgresql://{user}:{password}@{database}?host=/cloudsql/{project_id}:{location}:{instance_id}
- Cloud Run配置:已在控制台「Cloud SQL Connections」中关联对应Cloud SQL实例
{project_id}:{loc}:{instance_id} - 未使用Cloud SQL Proxy或VPC
问题现象
日志显示数据库连接成功,但查询core-db的public schema表时返回空集合,无报错:
日志代码
export const prismaClientWithLogger = new PrismaClient({ log: ['query', 'info', 'warn', 'error'], }) export const pingDB = async () => { try { await prismaClientWithLogger.$connect() console.log(`>> Prisma connected successfully with ${process.env.DATABASE_URL}`) const tables = await prismaClientWithLogger.$queryRaw`SELECT tablename FROM pg_tables WHERE schemaname='public';` console.log(`Tables: ${JSON.stringify(tables)}`) } catch (error) { console.log(`>> Prisma failed to connect with ${process.env.DATABASE_URL}: ${error}`) } finally { await prismaClientWithLogger.$disconnect() } }
日志输出
process.env.DATABASE_URL=postgresql://{user}:{password}@{database}?host=/cloudsql/{project_id}:{loc}:{instance_id} >> Prisma connected successfully with DATABASE_URL Tables: []
本地执行相同查询能看到public schema下的应用表,但Cloud Run环境中返回空数组。访问应用时还会报错:PrismaClientKnownRequestError: The table public.User does not exist in the current database.,进而触发内部服务器错误。
补充信息
- 怀疑连接字符串有问题,但日志显示连接成功且无连接错误
- 换用其他具备权限的用户也无法解决
- 应用访问时触发表不存在的错误
排查与解决方案
1. 确认连接的数据库是否正确
检查生产环境连接URL中{database}占位符是否填的是core-db——如果误填成默认的postgres库,自然看不到目标库的表。可以在pingDB函数里加一行代码验证当前连接的数据库:
const currentDB = await prismaClientWithLogger.$queryRaw`SELECT current_database();` console.log(`Current database: ${JSON.stringify(currentDB)}`)
2. 确保迁移已同步到生产库
本地开发时执行了Prisma迁移,但生产环境是否同步执行?Cloud Run部署时需要把迁移命令放在应用启动前:
- 在Dockerfile中添加:
RUN npx prisma migrate deploy
- 或者在Cloud Run启动命令中先执行迁移再启动应用:
npx prisma migrate deploy && npm start
3. 修正连接字符串格式
Google Cloud SQL的Unix套接字连接URL需要注意两点:{database}必须是目标库名core-db,另外可以显式指定默认schema。修改后的URL示例:
postgresql://{user}:{password}@localhost/core-db?host=/cloudsql/{project_id}:{location}:{instance_id}&schema=public
4. 检查Cloud Run服务账号权限
确保Cloud Run使用的服务账号拥有Cloud SQL Client角色,且该账号已被授权访问目标Cloud SQL实例。可前往IAM控制台验证权限配置。
5. 确认数据库用户的默认schema
如果生产环境的数据库用户默认schema不是public,查询时会找不到表。执行以下SQL检查并修改:
-- 查看用户默认schema SELECT usename, useconfig FROM pg_user WHERE usename='{user}'; -- 修改默认schema为public ALTER ROLE {user} SET search_path TO public;
内容的提问来源于stack exchange,提问作者Robert Christian

