你只是把 ORM 升了个大版本,npx prisma 一跑,直接报错说 datasource 的 url 属性不再支持写在 schema 文件里。升级说明没看,踩了个正着。
现象
执行 Prisma 命令行时报错,大意是:
Error: The datasource property `url` is no longer supported in schema files.
Move the connection string to `prisma.config.ts` instead.
而 schema 文件里的 datasource 块原本是这么写的:
datasource db {
provider = "postgresql"
url = env("DATABASE_URL") // 这一行不再允许
}
升级前一切正常,升级后所有 prisma 命令都跑不了——generate、migrate、studio 全挂。应用启动时的客户端构造也可能受影响。
这个报错还算友好,它直接告诉你去哪儿改。但如果没有提前准备,就会卡在那里。
值得留意的是失败的范围:不是某一个命令出问题,而是所有 prisma 命令一起挂。这本身就是"配置模型变了"的信号——如果是数据库连不上,generate 这类不需要连库的命令通常还是能跑的。
根因
该 ORM 从某个大版本起改了配置模型,连接串的定义位置被移出了 schema 文件。
设计意图是把"数据模型定义"和"运行时 / 迁移用的连接配置"解耦——schema 只描述数据结构(表、字段、关系),连接信息属于环境配置,放在项目级配置文件里更合适。
这个变更属于破坏性变更(breaking change)。因为是主版本升级,这类变更被允许存在,但因为升级时没读迁移说明,所以是在命令报错时才发现的。
背后的思路其实很合理:同一个 schema 可能要在多个环境、多种连接方式下使用(本地开发、CI、生产、测试库)。把连接串固定在 schema 里,等于把环境信息混进了数据模型,切换环境都要改同一份文件。挪到独立配置后,schema 保持"纯结构",连接随环境变,职责更清晰。
解决
有三条路,按需求选择。
方案一(跟随新模型,推荐):把连接串从 schema 里移出去。
// schema.prisma —— 移除 url
datasource db {
provider = "postgresql"
// url 不再写在这里
}
在项目根目录建一个专用的配置文件:
// prisma.config.ts
import { defineConfig } from 'prisma/config';
export default defineConfig({
datasource: {
url: process.env.DATABASE_URL,
},
});
同时客户端改用驱动适配器构造:
import { PrismaPg } from '@prisma/adapter-pg';
import { PrismaClient } from '@prisma/client';
const adapter = new PrismaPg({
connectionString: process.env.DATABASE_URL,
});
const prisma = new PrismaClient({ adapter });
注意这里用的是 process.env 而不是 schema 里的 env() 函数——后者是 schema 语法的东西,在配置文件里不适用。
方案二(不折腾):把版本锁在旧的大版本。
npm install prisma@<旧大版本> @prisma/client@<旧大版本> --save-exact
用 --save-exact 避免下次 npm update 又给你升上去。等有充足时间再迁移。
方案三:如果用的是托管平台,注意有些平台会自动改你的 schema、帮你注入连接串。升级时要留意它做了什么改动,否则可能和本地的配置冲突。
延伸与预防
这条最重要的教训是:ORM 大版本升级先读迁移说明,别等命令报错。
具体习惯:
一、升级前先看 changelog 里的 "Breaking Changes" 章节。 大多数成熟项目都会单独列出来,花五分钟看一遍,比事后排查一小时划算。
二、在独立分支上升级并把迁移跑通再合并。 不要在主干上直接升,否则会把所有人的开发阻塞住。
三、升级后跑一遍完整的命令链,而不是只看 npm install 没报错就当成功了。
npx prisma generate
npx prisma migrate dev --name check
npx prisma studio &
# 然后启动应用,走一遍真实的读写流程
npm install 成功只说明"包装上了",不说明"代码还能跑"。这个区别在所有依赖升级场景里都值得记住——尤其是 ORM、认证库、构建工具这三类,它们的破坏性变更是最频繁也最容易被低估的。
还有一点值得留意:这次变更影响的不只是命令行,运行时构造客户端的代码也要跟着改。即使命令行修好了,如果应用还在用"从 schema 隐式读取连接串"的老写法,启动时同样会失败。改完记得把应用也跑一遍,别只验证 npx prisma 那几条命令。
另外,如果项目里有环境变量校验、或者流水线里用 prisma validate 做检查,记得同步更新——把校验从 schema 相关的检查挪到新配置文件上。否则可能出现"本地能跑、流水线报错"的落差。