如何使用Prisma和SQLite建立一个Node.js数据库

2,060 阅读3分钟

最近,我看到很多关于Prisma的推文和文章。它是一个现代ORM(对象关系映射工具),可以与Node.js和TypeScript一起使用。

是的,这个库将帮助你建立和管理你的Node.js数据库--而且它与TypeScript兼容!它将生成你的所有类型的数据库。它将自动生成你的实体的所有类型。

模式定义很容易被人类读懂--那里不再有令人头痛的问题。在接下来的章节中,你会看到它是如何工作的。

另外,ORM与Next.js、GraphQL、Nest.Js、Express.js、Apollo和Hapi配合得很好。

总而言之,Prisma是一个现代的ORM,可以与所有的趋势技术栈很好地配合。

这就是为什么我决定尝试它并取代我以前的数据库管理库。TypeORM

"Prisma帮助应用程序开发人员更快地构建,并通过PostgreSQL、MySQL和SQLite的开源ORM减少错误。"-Prisma主页

让我们使用Node、Prisma和SQLite建立一个简单的Twitter数据库

练习的时间到了。我将向你展示如何使用Prisma建立你的第一个Node.js数据库。为了使这个介绍易于理解,我们将使用Node与SQLite。

SQLite是一个独立的数据库引擎。这意味着你不需要在你的计算机上配置一个数据库。如果你按照本教程的步骤操作,该项目将自行运行。

如果将来你想使用Prisma和PostgreSQL数据库,这里有一个关于使用Docker-Compose创建PostgreSQL数据库的教程

先决条件

  • Node.js(12.2或更高)

在开始之前,花点时间仔细检查一下你是否有12.2或更高版本的Node.js。如果你没有,在开始下一节之前更新你的Node即可。

注意:如果你想检查你的Node.js版本,你可以在终端输入:node -v 。输出的结果将是版本。

  • 基本的SQL知识

尽管我对这个新库采取了简单的方法,但我还是建议你有基本的SQL知识,以充分理解本教程。

注意:你不需要成为一个专家!你只需要掌握基本的知识,如创建一个表。这里只有创建一个表和提出一些请求这样的基础知识是必不可少的。

如何建立一个基本的Twitter项目

首先,你需要为这个项目创建一个新的文件夹并移入其中:

$ mkdir minimalistic-twitter
$ cd minimalistic-twitter

然后,我们将安装所有必须的依赖项,如TypeScript和Prisma:

$ npm init -y
$ npm install prisma typescript ts-node @types/node --save-dev
$ npm install @prisma/client

从现在开始,你应该在你的资源库中看到一个node_modules 文件夹和一个package.json 文件。

在进入Prisma初始化之前,最后一个配置步骤是在版本库根部为TypeScript创建一个配置。

要做到这一点,你可以创建一个tsconfig.json ,并粘贴以下配置:

{
  "compilerOptions": {
    "sourceMap": true,
    "outDir": "dist",
    "strict": true,
    "lib": ["esnext"],
    "esModuleInterop": true
  }
}

TypeScript默认配置(tsconfig.json)

我们走吧!现在是时候在我们的项目中使用Prisma了。在minimalistic-twitter 文件夹中,你可以使用以下命令来提示Prisma帮助输出。

$ npx prisma

现在,在建立我们的简约Twitter应用程序之前的最后一步是初始化数据库配置。

我们将使用init 命令,但有一个--datasource-provider 参数来设置数据库类型。否则,在默认情况下,init 将创建一个PostgreSQL数据库。

$ npx prisma init --datasource-provider sqlite

当命令执行完毕后,你应该在你的资源库中发现一个.env 文件和一个prisma 文件夹,里面有一个schema.prisma 文件。

schema.prisma 文件包含所有连接到数据库的指令。稍后它还将包括生成数据库表的说明。

.env 文件包含你的项目运行所需的所有环境变量。对于Prisma,唯一的变量是DATABASE_URL 。它的值被设置为./dev.db

dev.db 文件将是自成一体的数据库文件:

Project tree after the project initialization

项目初始化后的项目树

如果你有相同的输出,恭喜你,这意味着你的项目已经准备好了!🎉

如何建立我们的第一个模型--用户

我们的基本Twitter数据库将由两个主要实体组成。

  • 一个用户实体,包含用户信息和其推文
  • 一个包含推文内容和作者的推文实体。

首先,我们将专注于用户实体的创建。每个实体都有

  • 一个ID
  • 一个唯一的电子邮件(两个用户不能有相同的电子邮件)
  • 一个用户名
  • 一个推文列表

使用Prisma,如果我们想定义一个新的模式(模型),我们需要在schema.prisma 文件中进行。

为了定义一个实体,我们将使用下面的model 指令。你可以在你的schema.prisma 文件中的数据库连接指令之后复制它:

// After the database connection

model User {
  // We set an `id` variable
  // With an `Int` type (number)
  // Then, we set the Prisma decorators:
  // - @id (because it's an ID)
  // - @default(autoincrement()) (default value is auto-incremented)
  id Int @id @default(autoincrement())

  // We set an `email` variable
  // With a `String` type
  // Then, we set the Prisma decorator:
  // - @unique (because we want the user to be unique
  // based on the email - two users can't have the same)
  email String @unique

  // We set a `username` variable
  // With a `String` type
  username String

  // We set a `tweets` variable
  // With a `Tweet[]` type (one-to-many relationship)
  // Because each user can have between
  // 0 and an infinite number of tweets
  tweets Tweet[]
}

使用Prisma ORM的用户模型

正如你可能注意到的,我们还没有Tweet 模型。这将是我们的下一个步骤。

如何建立我们的第二个模型 - Tweet

现在我们有了用户,我们需要推特。让我们按照之前的过程来做,但这次是针对Tweet 实体。

每个人都有:

  • 一个ID
  • 一个创建日期
  • 一个文本
  • 一个userId(推特的作者)。

下面,你会发现这个实体。你可以在你的schema.prisma 文件中的User 模型声明后复制它。

// After the database connection

// After the User model

model Tweet {
  // We set an `id` variable
  // With an `Int` type (number)
  // Then, we set the Prisma decorators:
  // - @id (because it's an ID)
  // - @default(autoincrement()) (default value is auto-incremented)
  id Int @id @default(autoincrement())

  // Save the tweet creation time
  createdAt DateTime @default(now())

  // We set a `text` variable
  // With a `String` type
  text String

  // We set a `userId` variable
  // With an `Int` type (number)
  // It will link the `id` of the `User` model
  userId Int

  // We set a `user` variable
  // With a `User` type (many-to-one relationship)
  // Because each tweet has an author
  // This author is a `User`
  // We link the `User` to a `Tweet` based on:
  // - the `userId` in the `Tweet` model
  // - the `id` in the `User` model
  user User @relation(fields: [userId], references: [id])
}

使用Prisma ORM的Tweet模型

如何生成我们的第一个数据库迁移

在使用我们的数据库之前,我们需要做的第一件事就是生成它。为了做到这一点,我们将使用Prisma CLI的另一个命令。这个命令将允许我们创建迁移。

如果我们看一下关于migrate 命令的文档,我们会看到以下内容。

"Prisma Migrate是一个重要的数据库模式迁移工具,它使你能够。使你的数据库模式与你的Prisma模式保持同步,因为它在不断发展*,并维护*你数据库中的现有数据。"-Prisma migrate文档

这里的想法是保存我们的第一个数据库实现。你可以通过在终端键入下面的命令来完成它。

npx prisma migrate dev --name initialize

**注意:**你可以在--name 参数后输入你选择的名称。请记住,迁移名称有助于记住你所做的修改。

如果你的迁移命令是成功的,这意味着schema.prisma 中的所有指令都是正确的。✅

你的项目树现在应该类似于下面的图片(除了迁移哈希值)。

Project tree after the migration generation

迁移生成后的项目树

**注意:**在migration.sql 文件中,你可以找到生成数据库的SQL查询。

你的数据库已经准备好了!🚀 是时候试试了,添加一些用户,并让他们发推文。

如何测试我们的Node JS SQLite项目

那么,用户现在可以发推了吗?让我们试着在我们的数据库上运行一些查询。我们将在版本库根部创建一个index.ts 文件,并在其中写入一些指令。

首先,我们需要导入和初始化数据库连接。根据Prisma快速入门文档,我们创建一个prisma 变量来与数据库交互,并创建一个函数来编写我们的测试代码。

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

const prisma = new PrismaClient();

async function main() {}

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

我们准备在main 函数中填入一些指令。

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

const prisma = new PrismaClient();

async function main() {
  // We create a new user
  const newUser = await prisma.user.create({
    data: {
      email: "hello@herewecode.io",
      username: "gaelgthomas", // <- it's also my Twitter username 😄
    },
  });

  console.log("New User:");
  console.log(newUser);

  // We create a new tweet and we link it to our new user
  const firstTweet = await prisma.tweet.create({
    data: {
      text: "Hello world!",
      userId: newUser.id,
    },
  });

  console.log("First tweet:");
  console.log(firstTweet);

  // We fetch the new user again (by its unique email address)
  // and we ask to fetch its tweets at the same time
  const newUserWithTweets = await prisma.user.findUnique({
    where: {
      email: "hello@herewecode.io",
    },
    include: { tweets: true },
  });

  console.log("User object with Tweets:");
  console.dir(newUserWithTweets);
}

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

注意:如果你想发现你可以使用的不同指令,一个好的Prisma文档页面是CRUD页面。

是时候运行index.ts 文件了。

在做之前,打开你的package.json 文件并搜索scripts 部分。你将需要添加一个命令,使用ts-node 来启动项目。

如果你愿意,你可以用以下代码替换你的scripts 部分:

"scripts": {
  "dev": "ts-node ./index.ts",
  "test": "echo \"Error: no test specified\" && exit 1"
},

然后,在你的终端,你可以输入下面的命令,并阅读输出,看看一切是否运行良好:

$ npm run dev

注意:在上面的命令中,我们从我们的package.json运行dev脚本。

NPM test output using Prisma

使用Prisma的NPM测试输出

它正在工作!你得到了你的第一个用户和tweet。👏 现在你已经用Prisma建立了你的第一个数据库,你可以为它添加一些功能。这里有一些想法。

  • 在用户实体中添加更多的信息(生日、地址、传记等)。
  • 添加一个喜欢系统(每条推文都可以有喜欢,每个用户都可以有一个喜欢的推文列表)

代码可以在Github上找到--Node JS与Prisma和SQLite

如果你想获得完整的代码,你可以在我的GitHub上找到它。

->GitHubPrisma SQLite实例

谢谢你读到最后!