@prisma/client尚未初始化。请运行“prisma generate”并尝试重新导入它。

26

我正在使用Prisma、Postgres、Docker和Kubernetes。

npx prisma migrate dev可以使用。

并且npx prisma generate生成以下输出:

✔ Generated Prisma Client (2.23.0) to ./node_modules/@prisma/client in 68ms
You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

但是当我尝试在我的路由文件中使用时,会出现错误:

new-route.ts

import { PrismaClient } from '@prisma/client';

const prisma = new PrismaClient();

我的 Docker 文件:

FROM node:alpine

WORKDIR /app
COPY package.json .
RUN npm install --only=prod
COPY . .

CMD ["npm", "start"]

1
我认为如果你复制 COPY prisma ./prisma/ 那应该可以工作。但是我比你落后几步,因为我无法使用错误消息 Error: P1001: Can't reach database server at auth-postgres-srv.default.svc.cluster.local:5432 来运行 npx prisma migrate dev - SakoBu
只是想要加入我的意见。最近花了半天时间试图弄清楚为什么在调用Prisma服务时我的模式更改没有被反映出来。结果发现我必须重新启动节点环境,或者像我喜欢做的那样重新启动整个IDE,然后更改开始反映出来。 - Haroon Ramay
9个回答

12

我知道这个问题已经被标记为已解决,但我想分享一下我的设置,供有兴趣的人参考。

Dockerfile

# Build image
FROM node:16.13-alpine as builder
WORKDIR /app

# Not sure if you will need this
# RUN apk add --update openssl

COPY package*.json ./
RUN npm ci --quiet

COPY ./prisma prisma
COPY ./src src
RUN npm run build

# Production image

FROM node:16.13-alpine
WORKDIR /app
ENV NODE_ENV production

COPY package*.json ./
RUN npm ci --only=production --quiet

COPY --chown=node:node --from=builder /app/prisma /app/prisma
COPY --chown=node:node --from=builder /app/src /app/src

USER node

EXPOSE 8080
CMD ["node", "src/index.js"]

package.json

{
  "name": "example",
  "description": "",
  "version": "0.1.0",
  "scripts": {
    "generate": "npx prisma generate",
    "deploy": "npx prisma migrate deploy",
    "dev": "npm run generate && nodemon --watch \"src/**\" --ext \"js,json\" --exec \"node src/index.js\"",
    "build": "npm run generate",
    "start": "npm run build && node build/index.js"
  },
  "prisma": {
    "schema": "prisma/schema.prisma"
  },
  "dependencies": {
    "@prisma/client": "^3.6.0"
  },
  "devDependencies": {
    "@tsconfig/node16": "^1.0.2",
    "@types/node": "^16.11.12",
    "nodemon": "^2.0.15",
    "prisma": "^3.6.0"
  }
}

我在 Kubernetes 上运行这个。为了与数据库和迁移保持顺畅,我运行一个 initContainer,执行 prisma migrate deploy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: EXAMPLE
spec:
  replicas: 1
  selector:
    matchLabels:
      app: EXAMPLE
  strategy:
    rollingUpdate:
      maxSurge: 100%
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: EXAMPLE
    spec:
      containers:
        image: DOCKER_IMAGE
        imagePullPolicy: IfNotPresent
        name: SERVICE_NAME
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
      initContainers:
      - command:
        - npm
        - run
        - deploy
        image: DOCKER_IMAGE
        imagePullPolicy: IfNotPresent
        name: database-migrate-deploy

这是我刚刚复制并去除了所有非必要内容的在线服务。

希望这对某些人有所帮助。


1
你如何在生产环境中运行 Prisma 迁移和种子数据?你只需要在 Dockerfile 中运行 generate 命令即可。 - marko kraljevic
谢谢,非常有用。但是,你能解释一下为什么要从构建镜像中复制 node_modules 吗?那样不会将所有开发依赖项覆盖到你精简的生产 node_modules 中,并使最终镜像变得臃肿吗? - JP Lew
1
@JPLew 您说得完全正确,那个语句不应该在那里。我正在更新我的答案。 - CalvinMcGee
2
据我所知,npx prisma generate 只会创建 ./prisma/generated 目录。因此,在 Dockerfile 中包含它是非常合理的。 - CalvinMcGee
我遇到了这个错误,错误:未知的binaryTarget linux-arm64-openssl-undefined,并且没有提供自定义引擎文件。我已经在schema.prisma中添加了二进制目标,但是我无法解决这个错误。binaryTargets = ["native", "rhel-openssl-1.0.x"] - Subash Shrestha

9

在开发时,我通常不使用Docker。但是每当我更改schema.prisma并且必须使用npx prisma generate时,都会遇到此问题。对我而言,解决方案是重新启动运行npm start的节点应用程序。也许如果您重新启动容器,它可能会起作用。

如果您在Kubernetes Pod内部,则可以使用终端访问Pod,然后提供生成命令。

kubectl exec -it pod_name sh
npx prisma generate

由Rafiq提供的解决方案,在Pod中运行npx prisma generate很可能是一个糟糕的选择-下次重新启动Pod时,它将再次失败。只需要在构建镜像时复制prisma目录即可。 - Codebling

6

这里有另一种解决方法。

由于 prisma 客户端需要使用 .prisma 文件夹,如下图或文档中所示,因此另一种解决方案是确保它随您的代码一起发送。您可以按照以下方式实现。

错误的方法:将生成的文件夹进行打包并传送

您可能会认为只需通过在.dockerignore文件中添加一个对 .prisma 文件夹的例外规则(请注意叹号),就可以将生成的文件包含在镜像中。

node_modules/
!nodes_modules/.prisma

但是 prisma 使用的查询引擎 对于每个操作系统都不同,因此可能会遇到问题。

正确的方法:使用图像生成文件

在构建命令之前,在 Dockerfile 中添加 RUN npx prisma generate。这样,在镜像创建过程中就会生成文件,您无需在每个容器上运行 prisma generate 命令。该方法的缺点是您的 Docker 镜像将更大。如果有问题,可以尝试其他答案。

需要 .prisma 文件夹来引用生成的代码


1
在运行npm install之前,如果您复制了prisma文件夹,则无需生成。 - Codebling

6

你忘记复制 prisma 目录了,因为生成 Prisma Client 需要 schema.prisma 文件。如果你还需要迁移,应该复制整个 prisma 目录。

你的最终 Dockerfile 应该包含以下内容:

WORKDIR /app
COPY package*.json .
COPY prisma ./prisma/ 
RUN npm install --only=prod

2
谢谢!这是正确的答案,只需在运行安装之前复制此文件夹,它就会正常工作。 - Codebling
1
对我来说很有效,谢谢! - Loktar
我之前很困惑,明明在Dockerfile中复制了prisma文件夹,为什么还是收到错误信息。但正如你所指出的,需要在运行npm install之前复制它。 - undefined

2
对我来说,我只是在我的package.json中的scripts下更改了start,以便在运行之前生成prisma类型:
"start": "npx prisma generate && nodemon server.ts"

这对我有用 - 我只是想把这个放在这里,为了任何遇到同样问题的人。

1
我在使用 Prisma、MongoDB 和 Next.js 部署到 Vercel 时遇到了同样的问题。我在我的 package.json 文件中添加了以下内容;
...
"vercel-build": "npx prisma generate && next build"
...

它对我起作用了。

0
我将导入地址从:"@prisma/client""@prisma/client/edge" 改为:"../../prisma/generated/client/edge" 我指定了生成文件夹所在的目录,该目录位于 prisma 文件夹中。

0
这个错误是因为 Docker 没有安装 devDependencies 而导致的,这意味着它没有捆绑Prisma CLI

为了解决这个问题,你可以将 prisma CLI 包添加到你的依赖项中,而不是 devDependencies。(确保在更新 package-lock.json 后运行 npm install)


0
如果你使用docker compose,可以尝试这个方法:
将以下内容添加到您的 Dockerfile 中: COPY prisma ./prisma/
将 prisma 目录添加到您的 docker-compose.yml 文件中的卷中: volumes: - /app/prisma
在我的情况下,docker-compose.yml文件将如下所示。
version: "3"

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: web
    restart: always
    volumes:
      - ./:/app
      - /app/node_modules
      - /app/.next
      - /app/prisma
    ports:
      - 3000:3000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接