关于Docker的Prisma介绍

884 阅读16分钟

使用Docker的Prisma介绍

在本教程中,我们将进一步了解Prisma生态系统。我们将建立一个简单的服务器,访问Prisma以读取其数据库模式,并在Docker容器上运行。

在某些时候,你可能需要为你的后端应用提供一个数据库,无论是用Python、Java还是Node.js。为了让后端与数据库通信,你需要一种方法将你的服务器连接到该数据库。

当用户发送请求写入数据库时,服务器会修改该数据并将其写入数据库。当有人写了一个请求数据的查询时,服务器会读取它,将它发送到数据库,然后返回一个带有请求数据的响应。这与仅仅从我们的一个静态数组中读取数据是不同的。

现在,为了连接到该数据库,你可以使用本地驱动程序。本机驱动程序是允许你连接到数据库的库。例如,当使用Node.js作为后端和MySQL作为数据库时,你可以选择使用Node.js NPM提供的MySQL本地驱动程序

然而,它们没有提供修改或验证数据结构的方法,也没有提供对数据库之间的关系进行建模的方法。这意味着你不能对你的数据关系进行建模、播种,或迁移它们。

有了本地驱动程序,数据库连接是使用编程语言的最基本实现的。

其他选择是使用ORM(对象关系映射器)。例如,在使用Node.js时,MongoDB提供了一个mongoose(一个NPM库)数据库驱动。这使得开发人员更容易将Node.js后端连接到MongoDB数据库。

ORM将向你介绍一些新的功能,比如。

  • 建模
  • 验证
  • 迁移数据
  • 描述不同数据字段之间的关系,等等。

如果你使用的是一个SQL数据库,你可以对你的模式进行建模,并选择你想使用的字段。你可以验证你的数据模型,例如,一个密码字段需要至少有六个字符,某个字段需要是整数,等等。

Prisma属于ORM的范畴,它具有典型ORM的所有功能,如mongoosesequelize。与其他ORM不同的是,Prisma带有一些其他的附加功能。

Prisma与数据库无关。Mongoose 只在MongoDB数据库上工作,而sequelize 只在基于SQL的数据库上工作。比方说,如果你决定从MongoDB切换到PostgreSQL,那么你将不得不重写你的大部分代码,因为这两个库的工作方式不同。但是,有了Prisma,重写代码是没有必要的。

Prisma支持大多数数据库,如PostgreSQL、MySQL、MongoDB、MariaDB,等等。因此,你可以选择一个适合你的应用结构的数据库。你还可以使用Prisma迁移数据库,而不必修改应用程序的代码结构。

先决条件

Prisma有助于生成类型安全的数据库模式。在创建数据库时,必须仔细考虑每一个细节以确定数据库的结构。

在这种情况下,Prisma将你从编写SQL查询中抽象出来。因此,你必须确保你的数据库模式是安全的。

  • 为了拥有这些安全的模式,确保你的文本编辑器中安装了Prisma,以帮助你编写类型安全的Prisma代码。
  • 在本教程中,我们将使用Visual Studio Code。一旦你安装了它,确保你安装了Prisma扩展。这个扩展为.prisma 文件添加了语法高亮。它通过建立专门为Prisma程序设计的稳健和类型安全的代码,帮助防止错误。
  • Prisma提供了一个Prisma工作室,允许你与.prisma 文件互动。确保你的计算机上安装了它。同时,确保安装了Node.js(至少64位)。
  • 本指南还使用Docker运行Prisma。确保你的电脑上安装了Docker,并且有一些运行和使用Docker的基本知识。

Prisma的主要组成部分

Prisma生态系统是由三个主要部分组成的。它们是。

Prisma migrate

Prismamigrate 作为数据库的版本控制。迁移是一种控制数据库模式先前版本的方法。这与Git的工作原理类似,你总是有一个代码版本的历史。

每当你改变数据库模式时,Prisma的migrate就会为新添加的模式创建一个新版本。这样,每当你的当前运行模式出现问题时,你可以随时检查并回滚到之前的稳定数据库模式。

Prisma客户端

提供一种写/类型安全的查询生成器的方法。Prisma将你从编写SQL查询中抽象出来。Prisma客户端将帮助设置和编写你的数据库,对数据验证进行建模,描述不同数据字段之间的关系,等等。

Prisma客户端提供了一个非常简单和直观的方法来设置这些,而不需要写一个SQL查询。Prisma客户端使你能够生成SQL查询,并帮助连接到你选择的数据库。

Prisma客户端还生成并提供函数或方法,可用于创建一个与数据库的有状态连接。然后我们可以用它来创建、删除、更新或进行与数据库有关的操作。

Prisma工作室

这是一个现代数据库GUI,用于与你的数据进行交互。它为你提供了一个可视化的表示,即模式是如何在.prisma 文件中表示的。通常情况下,你总是倾向于在连接或检查你的表或数据库时遇到困难。

如果你通过CLI命令验证表有困难,你倾向于使用像PHPMyAdmin这样的东西来可视化你数据库中的数据。

Prisma studio提供了同样的功能,它有一个最小的用户界面,让你看到数据库中的所有表。在这里,你可以检查数据库中的模型和数据集的类型。你可以删除记录、添加记录和执行任何操作--只有通过用户界面。

设置

让我们跳进去,看看Prisma能实现什么。

创建一个项目文件夹prisma-client-app ,并使用VSCode编辑器打开它。使用npm init -y ,初始化Node.js。然后,使用以下命令开始安装Prisma CLI和Prisma客户端。

npm install prisma @prisma/client

下一步是使用以下命令初始化你的Prisma项目。

prisma init

用于Node-API的Prisma引擎将被下载,并将创建一个带有schema.prisma 文件的Prisma文件夹。这是你开始配置Prisma客户端、你希望利用的数据库、数据库模型(模式开发)和决定数据关系的地方。

让我们把这个文件分解一下。

设置和理解Prisma客户端的数据模型

一般来说,模式语言是非常直观的,语法容易理解。当你开始你的Prisma项目时,将创建两个主要块。

生成器'。

这决定了在构建生成实际数据库查询的数据类型时要创建的资产。默认情况下,它被设置为。

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

'数据源

这定义了Prisma如何连接到你的数据库。这需要两个主要参数。

  • provider
  • url

provider 设置你要使用的数据库。这可以是sqlite,mysql,mongodb,postgresqlsqlserver

url 设置一个用于与数据库服务器连接的连接字符串。如果数据库在本地运行,你就添加提供与你想使用的数据库连接的本地主机服务器。

默认情况下,Prisma启动了PostgreSQL数据库。它创建了一个env 文件,让你根据运行数据库的服务器来添加你的DATABASE_URL

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

例如,如果你使用的是SQLite(基于文件的SQL数据库),你可以这样设置你的datasource

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

provider 表示你正在使用的数据库, ,设置本地SQLite数据库的文件路径。SQLite连接器的连接URL指向你文件系统中的一个文件。url

注意:在一个prisma.schema ,你只能有一个数据源块。另外,datasource sqliteDb 是惯例。你可以给你的数据源起任何名字,比如data source = "myDb"

建模模式

模型代表你的应用域的实体。一个模型映射到你数据库中的一个表。你可以有不同的模型来定义不同表之间的关系。

尽管这些模型可能看起来是一样的,但在设置与不同实体相关的数据类型时,可以看到其中的差异。

让我们跳进去,看看如何在PostgreSQL数据库中建模和表示实体。这将在schema.prisma 文件中实现,如图所示。

model Todo {
  id Int @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @default(now())
  title String
  description String?
  completed Boolean @default(false)
}

这个模型表示一个单一的数据库表。当这个模型被执行时,它将创建一个表Todo ,并添加上述每一个字段作为表的字段。

一般来说,每个字段都有一个名称和一个数据类型。例如,字段title 从上述Todo 模型中被分配了一个数据类型String 。你可以选择各种数据类型,如:IntStringBoolean ,等等。

表中的每个字段都与它自己的属性有关。在一个典型的表中,你会有一个id ,作为唯一的值(主键),唯一地识别每个值。

  • @id 是表 的主键。Todo
  • 主键可以通过在id 中添加参数@default() 来默认创建。通过这样做,每当创建一条新记录时,计数就会自动递增。
  • createdAt 和 保持当前时间。updatedAt
  • completed 取一个 数据类型,默认值为 。Boolean false
  • 字段description ,在类型String 的最后有一个? 。它标志着参数? 被添加到一个字段中,并且在创建新记录时,默认设置为NULL

注意:你可以向你的数据模型添加模式关系。当处理基于SQL的数据库时。有可能会有多个表。你可以将多个表与Prisma中的模型联系起来。

用docker创建和运行一个Prisma服务器

一旦你创建了你的数据模型,你将创建一个服务器,让你与你的数据库互动。Prisma将把你的数据模型连接到你喜欢的数据库模式。然后,一个API将消费你保存到数据库中的数据。

让我们创建一个基本的TypeScript API,使用Prisma来连接到PostgreSQL。

在这种情况下,你将包装整个应用程序,并使用Docker容器运行它。

如果你是Docker的新手,强烈建议你在进一步进行之前先看一下这些文章。

  • [Docker概念]
  • [Docker容器如何工作]

设置模式

现在我们可以创建一个名为dockerized-prisma-postgres-api 的项目文件夹并运行prisma init

正如前面所解释的,Prisma API的主要构建模块是配置schema.prisma 文件。在这里,你将使用PostgreSQL数据库作为数据源提供者。

因此,你的schema.prisma 文件生成器和数据源应该类似于以下代码块。

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

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

url 设置一个你的数据库服务器的连接字符串。在这种情况下,Prisma正在从.env 文件中读取这个字符串。

如果PostgreSQL数据库在本地运行,你要添加提供与PostgreSQL连接的本地主机服务器。例如,DATABASE_URL="postgresql://postgres:postgres@localhost:5432/TEST_DB?schema=public"

然而,如果你想用Docker运行PostgreSQL,那么localhost 别名将不起作用。在这种情况下,你的url 将是DATABASE_URL="postgresql://postgres:postgres@postgres:5432/Todo?schema=public" ,其中别名postgres 将是在Docker中运行PostgreSQL镜像的容器名称。

为了在Docker中运行,你的.env 文件应该有一个连接字符串,如下所示。

# use this DATABASE_URL for running PostgreSQL on Docker compose
DATABASE_URL="postgresql://postgres:postgres@postgres:5432/Todo?schema=public"

# for local development use this url in the .env file
# DATABASE_URL="postgresql://postgres:postgres@localhost:5432/TEST_DB?schema=public"

将你之前创建的数据模型添加到你的schema.prisma 文件中。

model Todo {
  id Int @id @default(autoincrement())
  createdAt DateTime @default(now())
  updatedAt DateTime @default(now())
  title String
  description String?
  completed Boolean @default(false)
}

设置一个Node.js TypeScript环境

现在让我们深入了解并配置一个基本的Prisma和PostgreSQL API。

你将需要安装必要的软件包,使你能够运行TypeScript代码并创建一个网络服务器。继续安装以下包。

  • typescript - 这个包允许你在Node.js应用程序中编写TypeScript代码。它增加了静态类型、类型检查和其他功能,帮助你扩展大规模的JavaScript应用程序。

要安装它,请运行。

npm install -D typescript --save-dev
  • prisma - 一个Prisma CLI,允许你为你的Prisma应用程序编写类型安全的查询。

要安装它,请运行。

npm install prisma --save-dev
  • ts-node -Ts-node允许你构建和执行你编写的任何TypeScript代码。

要安装它,请运行。

npm install -D ts-node --save-dev
  • @types/node -Types/node允许你在运行TypeScript代码时为Node.js添加类型定义。

要安装它,请运行。

npm install --save-dev @types/node
  • @prisma/client -Prisma/client是一个Prisma生态系统工具,帮助你拥有类型安全的数据库数据访问、数据建模等。
  • express -Express是一个可扩展的Node.js库,帮助你创建极简的基于网络的API。
  • @types/express -Types/express为Express添加了TypeScript的类型定义。

要安装这些依赖项,请运行。

npm install express @types/express @prisma/client

由于你正在使用TypeScript,运行tsc --init ,以自动创建一个tsconfig.json 文件,该文件在运行TypeScript代码时持有默认参数。

设置一个TypeScript Prisma服务器

在根目录下创建一个index.ts 文件,开始创建你的Prisma API,如下图所示。

  • 导入expressPrismaClient
import express, { Application, Request, Response } from 'express';
import { PrismaClient } from '@prisma/client'
  • 添加expressPrismaClient 中间件,以及服务器的端口号。
const app: Application = express();
const prisma = new PrismaClient()

app.use(express.json());
app.use(express.urlencoded({ extended: true }));

const port: number = 3000;
  • 添加一个基本的GET 路由来测试服务器。
// testing route
app.get("/", (_req, res: Response) => {
    res.send(`Server is running on port: ${port}`);
});
  • 在获取todos时为GET 路由添加一个路由。
// Getting todos route
app.get('/api/todos', async (req: Request, res: Response) => {
    try {
        const allUsers = await prisma.todo.findMany();
        return res.json({
            success: true,
            data: allUsers
        });
    } catch (error) {
        return res.json({
            success: false,
            message: error
        });
    }
});
  • 添加一个用于添加todos的POST 路由。
// Adding todo route
app.post('/api/todos', async (req: Request, res: Response) => {
    try {
        const { title, description, completed } = req.body;
        const newTodo = await prisma.todo.create({
            data: {
                title,
                description,
                completed
            }
        });
        return res.json({
            success: true,
            data: newTodo
        });
    } catch (error) {
        return res.json({
            success: false,
            message: error
        });
    }
});
  • 添加一个listen() 方法,在设定的端口号上执行服务器。
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
})

要运行服务器,使用ts-node ,在package.json 文件中添加一个ts-node 命令,如图所示。

"scripts": {
    "start": "ts-node index.ts"
},

你的基本服务器已经准备好了。现在让我们把整个API包裹在Docker中。

用Docker和Docker-compose运行Prisma服务器

创建Docker文件环境。这允许你设置必要的命令来在Docker容器上运行你的代码。

继续前进,在你的项目根部创建一个Dockerfile 。这个文件将有以下命令。

  • 添加Node.js Docker镜像。
FROM node:alpine
  • 创建一个目录,在Docker上运行应用程序。
WORKDIR /app
  • 添加一个COPY 命令,将项目文件复制到Docker的/app 目录。
# COPY package.json and package-lock.json files
COPY package*.json ./

# generated prisma files
COPY prisma ./prisma/

# COPY ENV variable
COPY .env ./

# COPY tsconfig.json file
COPY tsconfig.json ./

# COPY
COPY . .
  • 安装package.json 依赖项。
RUN npm install
  • 生成Prisma客户端。
RUN npx prisma generate
  • 在Docker上运行并公开服务器。
# Run and expose the server on port 3000
EXPOSE 3000

# A command to start the server
CMD npm start

在运行COPY 命令时,有一些文件和文件夹你不想复制到Docker的工作目录。因此,你需要创建一个.dockerignore 文件,其中包含要排除的这些文件和文件夹的列表,如图所示。

node_modules

现在,你已经在Docker中准备好了配置。为了把所有的东西放在一起,包括PostgreSQL数据库和整个Prisma服务器,在你项目的根部创建一个docker-compose.yml 。然后,添加以下Docker服务。

version: "3.9"
services:
  postgres:
    image: postgres:latest
    container_name: postgres
    hostname: postgres
    ports:
      - 5432:5432
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: Todo
    volumes:
      - postgres-data:/var/lib/postgresql/data
    restart: unless-stopped

  pgadmin:
    image: dpage/pgadmin4
    container_name: pgadmin
    depends_on:
      - postgres
    ports:
      - "5555:80"
    environment:
      PGADMIN_DEFAULT_EMAIL: pgadmin4@pgadmin.org
      PGADMIN_DEFAULT_PASSWORD: admin
    volumes:
      - pgadmin-data:/var/lib/pgadmin
    restart: unless-stopped

  prisma-postgres-api:
    stdin_open: true
    build:
      context: .
      dockerfile: Dockerfile
    container_name: prisma-postgres-api
    depends_on:
      - postgres
    ports:
      - "3000:3000"
    restart: always

volumes:
  postgres-data:
  pgadmin-data:

这将运行三个服务。

  • postgres - 来执行和运行端口为 的Postgres数据库容器。为了访问数据库,将环境设置为 , , 和 。5432 POSTGRES_USER: postgres POSTGRES_PASSWORD: postgres POSTGRES_DB: Todo
  • pgadmin - Pgadmin将帮助你对Postgres数据库有一个可视化的展示。它有一个交互式的用户界面,让你看到你所操作的数据。Prisma自动设置这个数据库和表。
  • prisma-postgres-api - 这个服务运行你刚刚创建的Prisma API。它将访问Postgres服务,运行Prisma模式并将我们的数据模型填充到数据库中。

一切都准备好了。现在,让我们运行这个应用程序,让Docker容器化应用程序实例,这样你就不需要在你的本地计算机上配置任何东西。

要在Docker上运行这个,确保你的Docker正在运行,并执行这个命令。

docker-compose up

这条命令将运行Docker文件中指定的所有命令,为设定的服务拉取图像,并将所有东西包裹在一个容器中。

一旦整个过程完成,Docker将运行启动命令并在设定的容器内运行API。

running-api

如果你对项目文件做了一些修改,请运行docker-compose build ,然后重新运行docker-compose up 命令。

测试Docker API

该应用程序正在Docker容器上运行。让我们测试一下它是否像预期的那样工作。

导航到你的Docker并检查你正在运行的dockerized-prisma-postgres-api 容器。

prisma-postgres-api

然后,将鼠标悬停在prisma-postgres-api ,打开集成的Docker API。

api-cli

这将启动一个交互式CLI来运行你的API命令。在这种情况下,你要运行prisma migrate 命令。这将允许你的数据库与你所创建的模式同步。

如图所示,继续在交互式Docker CLI中运行npx prisma migrate dev

docker-api

现在我们来测试一下docker化的API。

要做到这一点,首先,使用pgadmin 接口访问Postgres数据库。这将让你看到你添加到数据库服务器的数据。

在你的浏览器上打开http://localhost:5555/ 。然后,使用用户名pgadmin4@pgadmin.org 和密码pgadmin 登录,正如我们在dockercompose.yml 文件中设置的那样。

打开Postman,开始测试API端点。首先运行测试GET 路线http://localhost:3000

test-route

使用路由http://localhost:3000/api/todos ,测试dockerizedPOST 路由是否工作,如下图所示。

post-api

这里,是输入数据的样本。

{
  "title": "Testing Dockerized Prisma API",
  "description": "a simple server that accesses Prisma to read its database schema a Docker container",
  "completed": false
}

一旦你点击发送按钮,一个新的todo将被创建,下面的响应将被记录在Postman上。

post-response

最后,你可以使用GEThttp://localhost:3000/api/todos ,检查这个新的todo,如下图所示。

post-api

总结

本指南帮助你了解了Prisma。在本教程中,你使用PostgreSQL数据库创建了一个基本的API,并通过Docker容器运行它。

Docker使我们能够创建整个API,而无需在本地计算机上配置PostgreSQL和Node.js。