使用 Next.js 实例化 Prisma Client 的最佳实践
提示
如果你想学习如何使用 Next.js 和 Prisma ORM 构建应用程序,请查看此全面的视频教程.
问题
许多用户在使用 Next.js 开发时遇到了此警告
warn(prisma-client) There are already 10 instances of Prisma Client actively running.
在开发环境中,命令 next dev
会在运行时清除 Node.js 缓存。这反过来又会由于热重载导致每次都初始化一个新的 PrismaClient
实例,从而创建一个与数据库的连接。由于每个 PrismaClient
实例都拥有自己的连接池,这会导致数据库连接很快耗尽。
解决方案
在这种情况下,解决方案是实例化一个 PrismaClient
实例并将其保存在globalThis
对象上。然后,我们进行检查,仅在 globalThis
对象上不存在 PrismaClient
时才实例化 PrismaClient
,否则如果 PrismaClient
实例已存在,则使用相同的实例来防止实例化额外的 PrismaClient
实例。
db.ts
import { PrismaClient } from '@prisma/client'
const prismaClientSingleton = () => {
return new PrismaClient()
}
declare const globalThis: {
prismaGlobal: ReturnType<typeof prismaClientSingleton>;
} & typeof global;
const prisma = globalThis.prismaGlobal ?? prismaClientSingleton()
export default prisma
if (process.env.NODE_ENV !== 'production') globalThis.prismaGlobal = prisma
你可以通过在实例化 Prisma Client 时附加 $extends
客户端方法来使用 Prisma Client 扩展来扩展 Prisma Client,如下所示
import { PrismaClient } from '@prisma/client'
const prismaClientSingleton = () => {
return new PrismaClient().$extends({
result: {
user: {
fullName: {
needs: { firstName: true, lastName: true },
compute(user) {
return `${user.firstName} ${user.lastName}`
},
},
},
},
})
}
创建此文件后,你可以在 Next.js pages
中的任何地方导入扩展的 PrismaClient
实例,如下所示
// e.g. in `pages/index.tsx`
import prisma from './db'
export const getServerSideProps = async () => {
const posts = await prisma.post.findMany()
return { props: { posts } }
}