# Learn Prisma

这篇文章 Next.js 使用 Drizzle-ORM 中,我们学习使用了 Drizzle ORM (opens new window) 库,Prisma (opens new window)Drizzle ORM (opens new window) 一样都是下一代 Node.js ORM,都提供类型安全的数据库访问、迁移和可视化数据编辑等功能。

Prisma 当前版本是 V7.8.0

# Prisma VS Drizzle-ORM

Prisma 和 Drizzle ORM 都是面向 TypeScript 的数据库工具,都支持类型安全查询和数据库迁移。简单来说,Drizzle 更像一个接近 SQL 的 Query Builder,适合喜欢直接控制 SQL 的开发者;Prisma 更像一套完整的 ORM 工具链,适合希望用统一 schema、自动类型生成和更高层 API 来管理数据库的项目。

对比项 Prisma Drizzle ORM
定位 更完整的 ORM 和数据工具链 更接近 SQL 的 Query Builder
Schema 定义 使用 schema.prisma 集中描述模型 使用 TypeScript 函数描述表结构
查询风格 prisma.user.findMany() 这类对象化 API select().from().where() 这类 SQL 风格 API
类型安全 根据 schema 生成完整类型 查询结果类型友好,但更依赖开发者写对 SQL 逻辑
关系查询 支持 includeselect、nested writes、relation filters 支持关系查询,但复杂关系更接近手写 SQL 思路
迁移 Prisma Migrate 根据 schema 生成 migration Drizzle Kit 根据 TS schema 生成 migration
上手门槛 不需要很深 SQL 基础 更适合熟悉 SQL 的开发者
适合场景 团队项目、复杂模型、长期维护 小型项目、偏 SQL、希望保持轻量

如果项目里数据库关系比较复杂、多人协作较多,Prisma 会更省心;如果项目更强调轻量、SQL 可控性,Drizzle ORM 会更直接。

# 初始化项目

使用 Prisma 非常简单,下面是使用 Prisma 的具体步骤:

  1. 安装依赖
$ npm install prisma @types/pg --save-dev
$ npm install @prisma/client @prisma/adapter-pg pg dotenv
1
2

每个软件包的功能:

  • prisma - Prisma CLI,用于运行诸如 prisma initprisma migrateprisma generate 之类的命令
  • @prisma/client - 用于查询数据库的 Prisma 客户端库
  • @prisma/adapter-pg - 用于将 Prisma 连接到 node-postgres 的适配器
  • pg - node-postgres
  • @types/pg - node-postgres 的 TypeScript 类型定义
  • dotenv - 加载 .env 环境变量
  1. 初始化 Prisma ORM

使用 Prisma CLI 命令创建 Prisma Schema (opens new window) 文件,从而设置 Prisma ORM 项目

$ npx prisma init --datasource-provider postgresql --output ../generated/prisma
1

这条命令会执行以下几项操作:

  • 创建一个 prisma/ 目录,其中包含一个 schema.prisma 文件,该文件包含您的数据库连接和 schema 模型。
  • 在根目录下创建一个 .env 文件,用于存放环境变量。
  • 创建用于 Prisma 配置的 prisma.config.ts 文件

配置文件 prisma.config.ts 保持不变

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

export default defineConfig({
  schema: "prisma/schema.prisma",
  migrations: {
    path: "prisma/migrations",
  },
  datasource: {
    url: env("DATABASE_URL"),
  },
});
1
2
3
4
5
6
7
8
9
10
11
12
  1. 修改 .env 环境变量,连接数据库
DATABASE_URL="postgresql://username:password@localhost:5432/db-name?schema=public"
1
  1. prisma/schema.prisma 文件里定义自己的 scheme
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

generator client {
  provider = "prisma-client"
  output   = "../generated/prisma"
}

datasource db {
  provider = "postgresql"
}

model User { 
  id    Int     @id @default(autoincrement()) 
  email String  @unique
  name  String?
  posts Post[]
} 
model Post { 
  id        Int     @id @default(autoincrement()) 
  title     String
  content   String?
  published Boolean @default(false) 
  author    User    @relation(fields: [authorId], references: [id]) 
  authorId  Int
} 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  1. 创建第一个迁移以设置数据库表
$ npx prisma migrate dev --name init
1

这个命令首先会根据 DATABASE_URL 的配置创建数据库,再根据 prisma/schema.prisma 的配置创建数据库表结构,最后生成迁移记录。

├── migrations
|  ├── 20260425053014_init
|  |  └── migration.sql
|  └── migration_lock.toml
└── schema.prisma
1
2
3
4
5
  1. 生成 Prisma Client
$ npx prisma generate
1

这个命令根据将根据 prisma/schema.prisma 文件d的 output 配置选项

generator client {
  provider = "prisma-client"
  output   = "../generated/prisma"
}
1
2
3
4

generated/prisma 目录下生成如下文件

├── browser.ts
├── client.ts
├── commonInputTypes.ts
├── enums.ts
├── internal
|  ├── class.ts
|  ├── prismaNamespace.ts
|  └── prismaNamespaceBrowser.ts
├── models
|  ├── Post.ts
|  └── User.ts
└── models.ts
1
2
3
4
5
6
7
8
9
10
11
12

尤其需要注意的是,models 文件夹,生成了 scheme 对应的对象文件。Prisma 通过这些文件将数据库操作转变为 JavaScript 对象操作

  1. 实例化 Prisma Client

将 Prisma ORM 驱动程序适配器的实例传递给 PrismaClient 构造函数

import "dotenv/config";
import { PrismaPg } from "@prisma/adapter-pg";
import { PrismaClient } from "../generated/prisma/client";

const connectionString = `${process.env.DATABASE_URL}`;

const adapter = new PrismaPg({ connectionString });
const prisma = new PrismaClient({ adapter });

export { prisma };
1
2
3
4
5
6
7
8
9
10
  1. 现在可以进行数据库操作了
import { prisma } from "./lib/prisma";

async function main() {
  const user = await prisma.user.create({
    data: {
      name: "Alice",
      email: "alice@prisma.io",
      posts: {
        create: {
          title: "Hello World",
          content: "This is my first post!",
          published: true,
        },
      },
    },
    include: {
      posts: true,
    },
  });

  const allUsers = await prisma.user.findMany({
    include: {
      posts: true,
    },
  });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

如果想由别的库((如 Drizzle-ORM)切换的 Prisma,使用 prisma db pull 检查现有数据库

$ npx prisma db pull
1

此命令读取 DATABASE_URL 环境变量,连接到数据库,并检查数据库模式。然后,它将数据库模式从 SQL 转换为 Prisma 模式中的数据模型。更多详情请参考 Add to Existing Project (opens new window)

# References