友好的数据建模和自动生成的,可编辑的迁移,用于Prisma
#node #database #prisma #migrations

一个聪明的人曾经说过...

automate-all-the-things

...那是我。

但是,除了所有笑话和模因之外,自动化都有助于减少在乏味和重复的任务上花费的时间。

本指南将教您如何建模数据库架构和使用Prisma自动生成可定制的SQL迁移。

先决条件

您的开发工具箱

要跟随,请确保您安装了以下内容:

注意:如果您没有安装Docker,则可以在Railway上设置免费的托管数据库或安装PostgreSQL

假设知识

本指南将要求您对以下技术有基本的熟悉:

  • javascript
  • GraphQl API
  • REST API

设置您的平台应用程序

在本教程中,您将使用以下启动器repository。它包含一个新的平台项目的设置文件。

要开始,请克隆存储库并结帐到koude0分支。

克隆存储库:

git clone -b automated-migrations https://github.com/ruheni/prisma-platformatic.git

现在,执行以下操作以开始:

  1. 导航到克隆目录:

    cd prisma-platformatic
    
  2. 安装依赖项:

    npm install
    
  3. 创建.env.example文件的.env文件:

    cp .env.example .env
    
  4. 使用Docker启动PostgreSQL数据库:

    docker-compose up -d
    

注意:如果您已经在本地运行了现有数据库服务器,请使用数据库的用户和密码值更新.env文件中的DATABASE_URL的值:

# .env
DATABASE_URL="postgres://<USER>:<PASSWORD>@localhost:5432/blog"

使用psql或您首选的SQL客户端连接到数据库实例。复制并运行以下SQL以创建数据库:

CREATE DATABASE blog;

项目结构和文件

该项目具有以下结构:

prisma-platformatic
  ├── .env.example
  ├── .env
  ├── .gitignore
  ├── README.md
  ├── docker-compose.yml
  ├── package-lock.json
  ├── package.json
  └── platformatic.db.json

目录中的值得注意的文件是:

  • .env:包含PostgreSQL数据库的数据库连接字符串。
  • docker-compose.yml:为您的PostgreSQL数据库定义Docker映像和配置。
  • package.json:定义您的应用程序依赖性。 koude15目前是项目中唯一的依赖性。
  • platformatic.db.json:定义Platformatic's configuration,例如服务器的主机名和端口,迁移目录和数据库的连接字符串。

数据建模和自动迁移

现在您已经设置了应用程序了,该是时候让您的双手弄脏Prisma!

在您的项目中设置Prisma

要开始,请首先安装Prisma CLI作为您项目中的开发依赖性:

npm install prisma --save-dev

Prisma CLI提供了允许您在项目中发展数据库模式的工具。

您现在可以使用以下命令在项目中初始化Prisma:

npx prisma init

该命令在包含schema.prisma文件的根部创建一个prisma文件夹。 schema.prisma文件是您数据库架构的真实源。

打开schema.prisma文件时,您应该看到以下内容:

// prisma/schema.prisma
generator client {
  provider = "prisma-client-js"
}

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

Prisma模式使用一种直观且可读的语言,称为Prisma Schema language

模式文件由三个主要组件组成:

  • 数据源:定义您的数据库连接详细信息,例如提供商和数据库的连接字符串。
  • Generator :定义当调用特定PRISMA命令时生成的资产。在这种情况下,将生成数据库的Prisma Client,是一个类型安全的查询构建器。
  • 数据模型:定义应用程序的实体将映射到数据库表(用于关系数据库)或集合(MongoDB)。该模式还没有任何内容,但是模型用model关键字表示,其次是实体名称。

建模您的数据库模式

对于本指南,您将创建一个Post模型,其中包括schema.prisma文件中的以下字段:

// ./prisma/schema.prisma
model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  viewCount Int      @default(0)
  createdAt DateTime @default(now())
}

上面的摘要定义了一个名为Post的模型,具有以下字段和属性:

  • id:自动插入整数将是模型的主要键。
  • title:非无效的String字段。
  • content:无效的String字段。
  • published:一个默认值为falseBoolean字段。
  • viewCount:一个默认值为0Int字段。
  • createdAt:一个DateTime字段,该字段的时间戳是该值创建为默认值。

请参阅Prisma documentation,以获取有关如何使用Prisma建模数据的更多详细信息。

migrate diff产生迁移

通过定义模式,您现在将使用koude39自动生成数据库迁移。

prisma migrate diff比较(或“ diffs”)两个模式, current 预期版本。当前版本是来自状态,预期版本是 to state。该命令生成一个描述更改的SQL脚本。

有趣的事实:如果您以前使用过koude41命令,它将在引擎盖下运行prisma migrate diff

命令,prisma migrate diff接受以下模式来源进行比较:

  • 实时数据库
  • 迁移历史
  • 模式数据模型(在Prisma模式中定义)
  • 一个空的模式

prisma migrate diff命令将使用以下参数生成迁移:

  • --from-schema-datasource:使用datasource块中定义的URL。
  • --to-schema-datamodel:使用Prisma模式中定义的数据模型。
  • --script可选):输出一个SQL脚本。

--from-schema-datasource--to-schema-datamodel也需要通往您的prisma架构文件的路径。

创建您将用来存储迁移历史的migrations目录:

mkdir migrations

platformatic使用migrations目录来存储和跟踪应用迁移的历史。

接下来,打开项目目录中的终端运行以下命令以自动生成您的第一个迁移:

npx prisma migrate diff \
--from-schema-datasource ./prisma/schema.prisma \
--to-schema-datamodel ./prisma/schema.prisma \
--script > migrations/001.do.sql \
--exit-code

注释

  1. 更新未来迁移的输出文件名,以防止覆盖001.do.sql的内容
  2. 您可以跳到Side quest部分,以了解如何使用koude54 Utility Library自动化版本控制和生成迁移
  3. 如果您省略了--script参数,则该命令将生成一个看起来像这样的人类可读摘要:
[+] Added tables
 - Post

命令在migrations目录中创建一个名为001.do.sql的文件,并具有以下内容:

-- migrations/001.do.sql
-- CreateTable
CREATE TABLE "Post" (
    "id" SERIAL NOT NULL,
    "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    "title" TEXT NOT NULL,
    "content" TEXT,
    "published" BOOLEAN NOT NULL DEFAULT false,
    "viewCount" INTEGER NOT NULL DEFAULT 0,

    CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
);

您会注意到命令生成了描述您在Prisma架构文件中定义的更改的SQL。

启动您的API服务器

在您的项目目录中,使用平台CLI将迁移应用于数据库:

npx platformatic db migrations apply

接下来,启动您的API服务器:

npx platformatic db start

命令将:

  • 启动平台API服务器
  • 从您的SQL数据库中自动生成rest和graphQl api

探索并与您的API互动

您现在可以在koude59上探索您的GraphQl API或koude60上的REST API。

在GraphIQL上运行以下突变,以在数据库中插入记录:

mutation INSERT_POST {
  insertPost(
    inputs: {
      title: "Prisma 💚 Platformatic"
      content: "Learn how you can auto-generate your database migrations using Prisma for Platformatic"
    }
  ) {
    id
    title
    content
    createdAt
    published
  }
}

您应该看到以下具有不同createdAt值的输出:

{
  "data": {
    "insertPost": [
      {
        "id": "1",
        "title": "Prisma 💚 Platformatic",
        "content": "Learn how you can auto-generate your database migrations using Prisma for Platformatic",
        "createdAt": "2022-10-08T14:26:08.101Z",
        "published": false
      }
    ]
  }
}

恭喜! ð

introspecty hour for versions型号的数据库

在引擎盖下,Platformatic使用Postgrator运行迁移。后生物在数据库中创建一个名为versions的表,以跟踪应用迁移。

versions桌子尚未在Prisma模式中捕获。当自动生成未来的迁移时,Prisma可能会促使您放下versions表,这不是理想的。

为了防止这种情况,您可以运行prisma db pull来内省数据库并使用缺失的模型填充Prisma架构:

npx prisma db pull

您的Prisma模式现在应该包含version型号:

// ./prisma/schema.prisma
model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  viewCount Int      @default(0)
  createdAt DateTime @default(now())
}

+model versions {
+  version BigInt    @id
+  name    String?
+  md5     String?
+  run_at  DateTime? @db.Timestamptz(6)
+}

@@ignore属性函数添加到模型中,以将其排除在Prisma客户端API中:

// ./prisma/schema.prisma
model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  published Boolean  @default(false)
  viewCount Int      @default(0)
  createdAt DateTime @default(now())
}

model versions {
  version BigInt    @id
  name    String?
  md5     String?
  run_at  DateTime? @db.Timestamptz(6)
+
+  @@ignore
}

sideQuestð§ð½:自动化版本控制和生成数据库迁移

在上一节中生成迁移的方法通常效果很好。唯一的警告是,您必须用每个迁移(即001.do.sql002.do.sql等)手动指定迁移文件的版本。

另一个摩擦点是命令很长,乏味,并且有可能发生错误。

为了解决这些摩擦点,我建立了一个名为koude54的公用事业库。该工具围绕prisma migrate diff命令包裹。它可以生成updown迁移。 @ruheni/db-diff还版本版本的迁移文件,并且是兼容后的。最重要的是,您可以为每个模式更改生成上下迁移。

另外,您也可以使用Kishan Gajerakoude76

安装助手实用程序

要开始,您可以将@ruheni/db-diff作为项目中的开发依赖性安装:

npm install --save-dev @ruheni/db-diff

更新您的模式

接下来,通过创建具有以下字段的User模型来更新Prisma模式:

  • id:具有自动插入整数的主要键
  • email:带有@unique约束的字符串值
  • name:字符串值(无效/不需要)
  • postsPostUser型号之间的一对一关系,分别是

您的Prisma模式应类似于下面的代码块中的模式:

// ./prisma/schema.prisma
model User {
  id    Int     @id @default(autoincrement())
  email String  @unique
  name  String?
  posts Post[]
}

model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  title     String
  content   String?
  published Boolean  @default(false)
  viewCount Int      @default(0)
  author    User?    @relation(fields: [authorId], references: [id])
  authorId  Int?
}

model versions {
  version BigInt    @id
  name    String?
  md5     String?
  run_at  DateTime? @db.Timestamptz(6)

  @@ignore
}

在此处展开​​以查看架构diff
// ./prisma/schema.prisma
+model User {
+  id    Int     @id @default(autoincrement())
+  email String  @unique
+  name  String?
+  posts Post[]
+}

model Post {
  id        Int      @id @default(autoincrement())
  createdAt DateTime @default(now())
  title     String
  content   String?
  published Boolean  @default(false)
  viewCount Int      @default(0)
+  author    User?    @relation(fields: [authorId], references: [id])
+  authorId  Int?
}

model versions {
  version BigInt    @id
  name    String?
  md5     String?
  run_at  DateTime? @db.Timestamptz(6)

  @@ignore
}

使用@ruheni/db-diff自动生成up迁移

接下来,使用@ruheni/db-diff自动生成up迁移:

npx db-diff --up

该命令应生成一个名为002.do.sql的新文件,并具有以下内容:

-- migrations/002.do.sql
-- AlterTable
ALTER TABLE "Post" ADD COLUMN     "authorId" INTEGER;

-- CreateTable
CREATE TABLE "User" (
    "id" SERIAL NOT NULL,
    "email" TEXT NOT NULL,
    "name" TEXT,

    CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

-- AddForeignKey
ALTER TABLE "Post" ADD CONSTRAINT "Post_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;

您可以通过仅通过--up进行up迁移或--down来指定要生成的迁移类型。

@ruheni/db-diff公用事业库将自动产生向上和向下迁移,如果您不提供--up--down标志。如果您维护迁移,请确保迁移版名称与UP迁移相当。

使用Platformatic CLI应用生成的迁移:

npx platformatic db migrations apply

使用platformatic重新启动并与您的API互动

重新启动API服务器:

npx platformatic db start

platformatic将重新生成graphQl和REST API。

http://localhost:3042/graphiql上打开graphiql并运行以下突变以在数据库中创建用户记录:

mutation INSERT_USER {
  insertUser(inputs: { name: "Alex", email: "alex@prisma.io" }) {
    id
    name
  }
}

展开以查看响应
{
  "data": {
    "insertUser": [
      {
        "id": "1",
        "name": "Alex"
      }
    ]
  }
}

运行另一个查询,将用户记录与您在上一步中创建的现有帖子记录联系起来:

mutation SAVE_POST {
  savePost(input: { id: 1, authorId: 1 }) {
    id
    title
    content
    author {
      name
    }
  }
}

展开以查看响应
{
  "data": {
    "savePost": {
      "id": "1",
      "title": "Prisma 💚 Platformatic",
      "content": "Learn how you can auto-generate your database migrations using Prisma for Platformatic",
      "user": {
        "name": "Alex"
      }
    }
  }
}

,你们都完成了! ð

包起来

回顾一下这部分所涵盖的内容,您:

  • 使用Prisma
  • 对数据库模式建模
  • 使用prisma migrate diff自动生成您的SQL迁移
  • 使用Platformatic创建了一个GraphQL和REST API
  • 使用@ruheni/db-diff实用程序自动生成并版本您的SQL迁移

下一篇文章将涵盖如何使用Prisma客户端扩展生成的GraphQL和REST API。

随意参考koude39 reference docs,以了解如何使用它来自动化数据库迁移工作流。如果您建造很酷的东西,您想与世界其他地区分享,请随时在此GitHub discussion thread中分享。

如果您遇到与koude54一起工作的任何问题,请随时使用create a GitHub issue或为图书馆做出贡献。

快乐黑客! ð