发布于 2026-01-06 5 阅读
0

下一代 ORM:Prisma Prisma 是什么?我们在做什么?架构 将更改应用到数据库 使用客户端

下一代 ORM:Prisma

Prisma是什么?

我们在制作什么?

模式

将更改应用到数据库

使用客户端

Prisma是什么?

Prisma是我用过的最好的数据库库之一。简而言之,你编写一个数据库模式,Prisma可以将更改应用到你的数据库,并生成一个专为你的数据库定制的TypeScript客户端库。

我们在制作什么?

在这个例子中,我将使用一个简单的博客应用程序。它有一个User表格和一个Article表。Users可以有多个Articles,每个表Article只有一个作者。

要安装 Prisma,请运行yarn add prisma -D

模式

prisma在项目根目录下的一个名为 `<path>` 的文件夹中,您可以创建一个名为 `<file>` 的文件schema.prisma。表格的描述(或“模式”)将存储在这里。

Prisma 使用此文件对数据库进行更改,并为我们生成自定义客户端。

图像

migrations暂时可以忽略这个文件夹。

数据源

要指定数据库的位置,您需要创建一个datasource代码块。

在以下代码片段中,我使用了一个 SQLite 数据库(一个轻量级数据库,适合快速测试应用程序,它将数据库存储在单个文件中)。对于 SQLite 数据库的“url”,我指定为database.db

SQLite

datasource db {
  provider = "sqlite"
  url      = "file:./database.db"
}
Enter fullscreen mode Exit fullscreen mode

Postgres

或者,您可以使用 Postgres 或 MySQL 作为数据库。

由于暴露 Postgres 数据库 URL 会危及数据库安全,我们可以将其存储为环境变量,避免直接写入代码。Prisma 支持.env 文件,它可以从名为 .env 的文件中加载环境变量.env,从而实现可移植的开发环境。

以下是Postgres数据库的代码片段示例:

datasource db {
  provider = "postgres"
  // Access the DATABASE_URL variable.
  url      = env("DATABASE_URL")
}
Enter fullscreen mode Exit fullscreen mode

发电机

还记得我说过 Prisma 可以为你生成客户端代码吗?

这段代码片段精确地指定了 Prisma 生成器将遵循的行为。对我来说,它运行得非常完美。

generator client {
  provider = "prisma-client-js"
}
Enter fullscreen mode Exit fullscreen mode

转盘是如何运转的……

现在,是时候添加表格了。在这个例子中,我将使用一个简单的博客应用。它有一个User表格和一个Article表。每个表Users可以有多个作者Articles,每个Article作者只能有一个账号。

我们将从每个用户的一些基本信息开始,以便我们熟悉 Prisma 的语法。

要开始创建表的模式,我们声明一个model代码块:

model User {
  // Our fields (columns) go here...
}
Enter fullscreen mode Exit fullscreen mode

我们将添加一个 ID 列(整数类型)、一个电子邮件列(字符串类型)和一个姓名列(字符串类型)。

model User {
  id          Int
  email       String
  name        String
}
Enter fullscreen mode Exit fullscreen mode

因为我们希望 ID 可以被索引,所以我们会添加@id装饰器。这是一个简单的应用,因此我们会让它的值对每个用户自动递增。

model User {
  id          Int    @id @default(autoincrement())
  email       String
  name        String
}
Enter fullscreen mode Exit fullscreen mode

因为我们希望每个用户的电子邮件地址都是唯一的,所以我们会添加@unique装饰器。

model User {
  id     Int    @id @default(autoincrement())
  email  String @unique
  name   String
}
Enter fullscreen mode Exit fullscreen mode

现在,我们来构建Article模型。我们将以与之前相同的方式创建一个 ID 字段,并添加标题字段、内容字段以及用于指定文章发布时间的字段。最后,我们将添加一个authorId字段,用于存储文章作者的 ID。

model Article {
  id          Int @id @default(autoincrement())
  authorId    Int
  title       String
  content     String
  publishedAt DateTime
}
Enter fullscreen mode Exit fullscreen mode

以下是 Prisma 支持的数据类型的完整列表。

我们的文章有一个名为 `<field_name>` 的字段,但如果有一个名为 `<field_name> ` 且类型为 `User` 的authorId字段岂不是更好?使用 Prisma,我们就能实现这一点!author

model Article {
  id          Int @id @default(autoincrement())
  authorId    Int
  author      User
  title       String
  content     String
  publishedAt DateTime
}
Enter fullscreen mode Exit fullscreen mode

我们还没完成,但也没剩下多少事要做了。

我们只需要使用@relation装饰器即可。

装饰器@relation使用以下语法:

@relation(fields: [authorId], references: [id])

让我们来分析一下。

fields属性指定引用中哪个字段存储Article作者的 ID。该references属性指定用户表中该fields属性指向的字段。

刚才的描述可能有点啰嗦,所以我直接给你展示一下它在模式图中的样子:

model Article {
  id          Int @id @default(autoincrement())
  authorId    Int
  author      User @relation(fields: [authorId], references: [id])
  title       String
  content     String
  publishedAt DateTime
}
Enter fullscreen mode Exit fullscreen mode

完美的。

最后一步。由于每篇文章都有作者,因此从逻辑上讲,每个用户都会有多篇文章。我们实际上无法避免将这一点添加到模式中。

为了在我们的模式中反映这一点,我们只需articlesUser模型添加一个字段。我们将它的类型设置为Article[]

model User {
  id       Int    @id @default(autoincrement())
  email    String @unique
  name     String
  articles Article[]
}
Enter fullscreen mode Exit fullscreen mode

schema.prisma呼!这篇文章到此结束。

最终schema.prisma效果图如下:

datasource db {
  provider = "sqlite"
  url      = "file:./database.db"
}

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

model User {
  id       Int    @id @default(autoincrement())
  email    String @unique
  name     String
  articles Article[]
}

model Article {
  id          Int @id @default(autoincrement())
  authorId    Int
  author      User @relation(fields: [authorId], references: [id])
  title       String
  content     String
  publishedAt DateTime
}
Enter fullscreen mode Exit fullscreen mode

将更改应用到数据库

现在,我们希望 Prisma 将这些更改应用到我们的数据库。这将自动生成自定义客户端 SDK。将更改应用到数据库的过程称为“迁移”。
应用这些更改的命令是:

yarn prisma migrate dev

最后一点dev表明我们正在开发环境中工作。

我们需要为迁移指定一个名称,所以我们就写上initial migration

如果一切顺利,输出结果将如下所示:

图像

现在,我们准备开始操作数据库了。

使用客户端

现在我们已经生成了客户端代码,可以开始使用 Prisma 了。

如果生成的客户端代码没有显示,请尝试运行以下命令:

yarn prisma generate

我们将把代码写在一个名为index.js. 的文件中。Prisma 也内置了 Typescript 支持。

要创建 Prisma 客户端的实例,我们PrismaClient从以下位置导入该类@prisma/client

const { PrismaClient } = require('@prisma/client');

const prisma = new PrismaClient();
Enter fullscreen mode Exit fullscreen mode

由于 Prisma 的客户端是为我们的数据库定制生成的,因此它具有内置的智能感知功能。

图像

让我们来看一些如何使用 Prisma 客户端的例子。

创建用户

首先,我们将创建一个用户。

这很简单:在 Prisma 中创建任何表都可以用以下方式完成prisma.[table name].create()


prisma.user.create({
  data: {
    name: 'Michael Fatemi',
    email: '<REDACTED>',
  },
});

Enter fullscreen mode Exit fullscreen mode

如果我们想要检索为用户自动生成的 ID:


prisma.user.create({
  select: {
    id: true
  },
  data: {
    name: 'Michael Fatemi',
    email: '<REDACTED>',
  },
});

Enter fullscreen mode Exit fullscreen mode

创建文章

由于每篇文章都引用一个用户,Prisma 不允许我们手动指定用户authorId,因为这可能会违反 SQL 创建的外键约束。因此,我们必须通过以下语法指定将用户“连接”到文章。


async function createArticle(authorId, title, content) {
  prisma.article.create({
    data: {
      author: {
        connect: {
          id: authorId,
        },
      },
      content,
      title,
      publishedAt: new Date(),
    },
  });
}

Enter fullscreen mode Exit fullscreen mode

列出用户撰写的文章

我们可以这样获取用户数据:


async function getArticles(userId) {
  return await prisma.user.findFirst({
    select: {
      articles: true
    },
    where: {
      id: userId
    }
  })
}

Enter fullscreen mode Exit fullscreen mode

列出在特定日期之前发表过文章的用户

这在现实世界中可能没什么用,但可以展示 Prisma 的强大功能。

此示例还展示了如何创建比检查值是否相等更复杂的查询。您还可以通过将对象而不是值传递给子句来检查值是否小于 ( lt)、大于 ( gt)、等于 ( ) 或其他情况。eqwhere


async function getUsersWhoWroteAnArticleBefore(date) {
  return await prisma.user.findMany({
    select: {
      id: true,
      name: true
    },
    where: {
      articles: {
        some: {
          publishedAt: {
            lt: date
          }
        }
      }
    }
  })
}

Enter fullscreen mode Exit fullscreen mode

感谢阅读本文,希望对您学习如何使用 Prisma 自动生成代码有所帮助!

文章来源:https://dev.to/myfatemi04/use-prisma-s-powerful-javascript-client-generator-to-write-a-blog-app-18gj