Prisma - 入门

发布时间 2023-08-21 19:44:26作者: OrzMiku

Prisma是一个开源的数据库工具链项目,支持PostgreSQL、MySQL、MongoDB、SQL Server和SQLite。下面我会使用Mysql + Typescript来作为演示。

安装Prisma

首选你需要有一个Node环境。然后新建一个文件夹,初始化Node项目。

npm init -y
npm i typescript ts-node --save-dev
npm i prisma --save-dev

初始化Prisma

npx prisma init

prisma会创建.env(环境变量)和prisma/schema.prisma(Prisma schema)

配置数据库

打开prisma/schema.prisma,修改数据库的provider为mysql

generator client {
  provider = "prisma-client-js"
}

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}

可以看到,这里的数据库地址使用了.env里的DATABASE_URL变量,我们去.env中修改一下。格式为mysql://username:password@ip:port/database

数据建模

术语 数据建模(data modeling) 是指 定义应用程序中对象的形状和结构的过程,这些对象通常被称为 "应用模型(application models)"。在关系型数据库中(例如 PostgreSQL),它们被存储在 表(tables) 中。当使用文档数据库(如 MongoDB)时,它们被存储在 集合(collections) 中。

在Mysql中,说白了就是搞一下表结构。打开Prisma schema(prisma/schema.prisma),添加下面代码:

model User {
  user_id Int     @id @default(autoincrement())
  name    String?
  email   String  @unique
  isAdmin Boolean @default(false)
}

这就代表有一张User表,有user_idnameemailisAdmin等字段。这有什么用,后面细说。

工作流程

有两种工作流程。使用Prisma Migrate + Prisma Client仅使用Prisma Client

  • 仅使用 Prisma Client:Prisma schema 中的应用模型是通过对你的数据库 schema 进行内省(introspection)来生成的。数据建模主要发生在数据库层面。
  • 使用 Prisma Client 和 Prisma Migrate:数据建模发生在 Prisma schema 中,通过 手动添加应用模型 来实现。Prisma Migrate 映射这些应用模型到底层数据库的数据表(目前仅支持关系型数据库)

Prisma Migrate

Prisma Migrate 是一个命令式数据库架构迁移工具,它可以:

  • 保持数据库架构与Prisma 架构的同步
  • 维护数据库中的现有数据

因此在刚刚数据建模后,你可以使用Prisma Migrate让数据库架构与Prisma架构保持同步。你可以使用prisma migrate dev来创建一个迁移,使用--name xxx的参数来指定本次迁移的名称。

prisma migrate dev --name init

使用上面命令,创建第一次迁移。这会为你做两件事,创建sql文件和执行sql文件。
你可以在migrations文件夹看到迁移历史记录。

如果一切顺利的话,现在数据库中就已经有了User表和对应的字段了。如果报错了,接着往下看。

影子数据库

这里有一个坑,Prisma Migrate 在运行以开发为中心的命令时会使用第二个临时数据库,例如:

prisma migrate dev
prisma migrate reset

这个数据库被称为影子数据库。但是有些人使用的云数据库可能没有权限创建数据库,然后就报错了。有两种解决方法,一种是给权限,另一种是再使用另一个数据库作为影子数据库。

这里说一下如何设定影子数据库,首选创建一个数据库作为影子数据库。然后在数据库的配置中加入shadowDatabaseUrl字段。

datasource db {
  provider          = "postgresql"
  url               = env("DATABASE_URL")
  shadowDatabaseUrl = env("SHADOW_DATABASE_URL")
}

我这里依然使用了env,在.env中再添加一个SHADOW_DATABASE_URL,并配置影子数据库的url即可。

影子数据库用户权限

数据库 数据库用户需求
SQLite 没有特殊要求。
MySQL 数据库用户必须具有 CREATE, ALTER, DROP, REFERENCES ON . 权限。
PostgreSQL 用户必须是超级用户或具有 CREATEDB 权限。请参见 CREATE ROLE (PostgreSQL 官方文档)。
SQL Server 用户必须是站点管理员或具有 SERVER 安全权限。请参见官方文档。

Prisma Client

Prisma Client 是一个自动生成的类型安全查询构造器。
我们只需要import { PrismaClient } from '@prisma/client',然后const prisma = new PrismaClient()即可,这会创建一个Prisma Client实例。如果这里报错,检查一下有没有安装@prisma/client
当你安装@prisma/client时,他会自动执行prisma generate,因此首次并不需要执行prisma generate
但是如果你修改了数据库结构, Prisma schema 被更改时,你需要手动执行一次npx prisma generate。当prisma generate执行后,这个命令读取你的Prisma模式并生成你的Prisma Client库。(这使得你的Prisma Client实例拥有刚刚数据建模中的数据模型)。

然后我们就可以通过Prisma Client访问这些数据模型,并对数据进行操作。

使用Prisma客户端编写第一个查询

创建一个名为的新文件index.ts并向其添加以下代码:

import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  // ... 在这里写一些查询
}

main()
  .catch((e) => {
    throw e
  })
  .finally(async () => {
    await prisma.$disconnect()
  })

因为目前数据库中没有数据,所以先写一些数据进去:

async function main() {
  await prisma.user.create({
    data: {
      name: '二次元虎哥',
      email: 'huge@shenyang.acg',
      isAdmin: false
    },
  })

然后npx ts-node index.ts执行。然后修改为查询代码:

async function main() {
  const allUsers = await prisma.user.findMany()
  console.log(allUsers)
}

然后执行文件,不出意外的话就可以看到刚刚写入的数据了。

然后试试更新数据:

async function main() {
  const user = await prisma.user.update({
    where: { name: "二次元虎哥" },
    data: { isAdmin: true },
  })
  console.log(user)
}

返回更新后的数据就说明更新成功了。上面提到的create,update和findMany只是Client的一部分Api。我会在后面的笔记中详细介绍其他Api。