프리즈마 요약

Mar 13 2023
Prisma는 데이터베이스 연결, 데이터 쿼리 및 데이터 조작을 위한 사용하기 쉬운 API를 제공하는 오픈 소스 데이터 관리 도구입니다. 서로 다른 데이터베이스에 대한 통합 데이터 액세스 계층을 제공하므로 기본 기술에 관계없이 동일한 방식으로 다른 데이터베이스와 상호 작용할 수 있습니다.

Prisma는 데이터베이스 연결, 데이터 쿼리 및 데이터 조작을 위한 사용하기 쉬운 API를 제공하는 오픈 소스 데이터 관리 도구입니다. 서로 다른 데이터베이스에 대한 통합 데이터 액세스 계층을 제공하므로 기본 기술에 관계없이 동일한 방식으로 다른 데이터베이스와 상호 작용할 수 있습니다. Prisma는 기본 데이터베이스를 추상화하고 데이터 작업을 위한 단순하고 형식이 안전하며 표현력이 풍부한 API를 제공합니다. Prisma를 사용하면 더 적은 코드를 작성하고, 버그 위험을 줄이고, 응용 프로그램의 성능을 개선할 수 있으므로 데이터 관리 요구 사항에 적합합니다. 이 기사에서는 Twitter 복제본을 생성하여 요약에서 프리즈마를 탐색할 것이므로 시작하겠습니다. ‍

프리즈마 설정

yarn 대신 모든 쿼리에 사용할 것입니다 npx. 설치되어 있지 않은 경우 를 사용하여 설치합니다 npm install — global yarn. 를 사용하여 디렉토리를 만들고 노드 프로젝트를 초기화합니다 yarn init. 를 사용하여 Prisma에 필요한 종속성을 설치합니다 yarn add -D typescript ts-node @types/node. 이러한 모든 개발 종속성은 Prisma가 Typescript ORM이므로 사용합니다. 이제 프로젝트의 루트 디렉토리에 파일을 yarn tsc — init생성하는 명령을 사용하여 TypeScript 프로젝트를 초기화합니다 . 명령을 사용하여 Prisma를 개발 종속성으로 설치하겠습니다.tsconfig.jsonyarn add -D prisma

프리즈마 초기화

Prisma에 대한 모든 요구 사항을 설정한 후 yarn prisma init — datasource-provider mysql. 콘솔, 생성된 Prisma 디렉토리 및 파일에 대한 다음 정보를 묻는 메시지가 표시됩니다 schema.prisma.

✔ Your Prisma schema was created at prisma/schema.prisma
  You can now open it in your favorite editor.

warn You already have a .gitignore file. Don't forget to add `.env` in it to not commit any private information.

Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Run yarn prisma db pull to turn your database schema into a Prisma schema.
3. Run yarn prisma generate to generate the Prisma Client. You can then start querying your database.

More information in our documentation:
https://pris.ly/d/getting-started

Done in 2.18s.

# Environment variables declared in this file are automatically made available to Prisma.
# See the documentation for more detail: https://pris.ly/d/prisma-schema#accessing-environment-variables-from-the-schema

# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB, and CockroachDB.
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings

DATABASE_URL="mysql://johndoe:randompassword@localhost:3306/mydb"

Prisma에서 모델 정의

사용자, 프로필 및 트윗이 있는 간단한 Twitter 복제본을 만들어 보겠습니다. 한 명의 사용자는 하나의 프로필을 가질 수 있지만 여러 개의 트윗을 가질 수 있습니다. 그러나 먼저 Prisma의 모델은 무엇입니까? 어떻게 사용합니까? 간단히 말해서 Prisma의 모델은 훨씬 더 쉬운 방법으로 데이터베이스를 쿼리하는 데 사용할 수 있는 데이터베이스에서 사용하는 테이블을 나타냅니다. schema.prisma이제 디렉토리 아래의 파일 에 모델을 생성해 봅시다 prisma.

// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

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

model User {
  id          String   @id @default(uuid()) // Primary Key and Default Value as UUID
  email       String   @unique // Unique Constraint
  password    String   @db.VarChar(60) // String with length 60 use bcrypt to hash password and store it
  phoneNumber String   @db.VarChar(15) // String with length 15
  isSuspended Boolean  @default(false) // Boolean with default value false
  isDeleted   Boolean  @default(false) // Boolean with default value false
  profile     Profile? // One To One Relation

  createdAt DateTime @default(now()) // DateTime with default value as now
  updatedAt DateTime @updatedAt // DateTime that will be updated on every update
}

model Profile {
  id        String  @id @default(uuid()) // Primary Key and Default Value as UUID
  userName  String  @unique @db.VarChar(7) // Allowed Characters -> A-Z,a-z,0-9 -> Total Possible Combination (26+26+9)^7
  isOnline  Boolean @default(false) // Boolean with default value false
  followers BigInt  @default(0) // BigInt with default value 0

  credential User   @relation(fields: [userId], references: [id], onDelete: Cascade) // On delete cascade
  userId     String @unique // One To One Relation

  tweets Tweet[] // One To Many Relation

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Tweet {
  id          String          @id @default(uuid()) // Primary Key and Default Value as UUID
  description String
  access      AccessModifier? @default(PUBLIC) // Enum with default value PUBLIC

  Profile   Profile? @relation(fields: [profileId], references: [id], onDelete: Cascade)
  profileId String?

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

// Access Modifier Enum
enum AccessModifier {
  PUBLIC
  PRIVATE
  SELF
}

migrations 명령을 실행하고 디렉터리를 확인하면 디렉터리 아래에 prisma 날짜가 있는 디렉터리가 있고 _init 이 디렉터리에는 Prisma가 생성하는 파일이 들어 있는 디렉터리가 표시됩니다 .sql.

-- CreateTable
CREATE TABLE `User` (
    `id` VARCHAR(191) NOT NULL,
    `email` VARCHAR(191) NOT NULL,
    `password` VARCHAR(60) NOT NULL,
    `phoneNumber` VARCHAR(15) NOT NULL,
    `isSuspended` BOOLEAN NOT NULL DEFAULT false,
    `isDeleted` BOOLEAN NOT NULL DEFAULT false,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,

    UNIQUE INDEX `User_email_key`(`email`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Profile` (
    `id` VARCHAR(191) NOT NULL,
    `userName` VARCHAR(7) NOT NULL,
    `isOnline` BOOLEAN NOT NULL DEFAULT false,
    `followers` BIGINT NOT NULL DEFAULT 0,
    `userId` VARCHAR(191) NOT NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,

    UNIQUE INDEX `Profile_userName_key`(`userName`),
    UNIQUE INDEX `Profile_userId_key`(`userId`),
    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- CreateTable
CREATE TABLE `Tweet` (
    `id` VARCHAR(191) NOT NULL,
    `description` VARCHAR(191) NOT NULL,
    `access` ENUM('PUBLIC', 'PRIVATE', 'SELF') NULL DEFAULT 'PUBLIC',
    `profileId` VARCHAR(191) NULL,
    `createdAt` DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3),
    `updatedAt` DATETIME(3) NOT NULL,

    PRIMARY KEY (`id`)
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

-- AddForeignKey
ALTER TABLE `Profile` ADD CONSTRAINT `Profile_userId_fkey` FOREIGN KEY (`userId`) REFERENCES `User`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

-- AddForeignKey
ALTER TABLE `Tweet` ADD CONSTRAINT `Tweet_profileId_fkey` FOREIGN KEY (`profileId`) REFERENCES `Profile`(`id`) ON DELETE CASCADE ON UPDATE CASCADE;

Environment variables loaded from .env
Prisma schema loaded from prisma\schema.prisma

✔ Generated Prisma Client (4.9.0 | library) to .\node_modules\@prisma\client in 153ms  
You can now start using Prisma Client in your code. Reference: https://pris.ly/d/client
```
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
```
Done in 3.01s.

Prisma 클라이언트를 사용하여 데이터베이스 사용

우리의 응용 프로그램에는 다섯 가지 주요 사항을 구현해야 합니다.

  • 사용자 만들기
  • 사용자 세부 정보 업데이트
  • 사용자 삭제
  • 모든 사용자 나열
  • 특정 사용자 찾기

// Path: Tables\UserTable.ts

import { PrismaClient, User } from "@prisma/client";
import { handlePrismaError } from "./PrismaError";
const prisma = new PrismaClient();

interface ICreateUser {
 email: string;
 password: string;
 phoneNumber: string;
}

export class UserTable {
 static create = async (newUser: ICreateUser) => {
  try {
   const user = await prisma.user.create({
    data: {
     ...newUser,
    },
   });
   return { user };
  } catch (e: any) {
   return { error: handlePrismaError(e) };
  }
 };
 static update = async (updateUser: User) => {
  try {
   const user = await prisma.user.update({
    where: {
     id: updateUser.id,
    },
    data: {
     ...updateUser,
    },
   });
   return { user };
  } catch (e: any) {
   return { error: handlePrismaError(e) };
  }
 };
 static delete = async (user: User) => {
  try {
   const deletedUser = await prisma.user.delete({
    where: {
     id: user.id,
    },
   });
   return { deletedUser };
  } catch (e: any) {
   return { error: handlePrismaError(e) };
  }
 };
 static getAll = async (includeProfile: boolean = false) => {
  try {
   const users = await prisma.user.findMany({
    include: {
     profile: includeProfile,
    },
   });
   return { users };
  } catch (e: any) {
   return { error: handlePrismaError(e) };
  }
 };
 static getById = async (id: string, includeProfile: boolean = false) => {
  try {
   const user = await prisma.user.findUnique({
    where: {
     id,
    },
    include: {
     profile: includeProfile,
    },
   });
   return { user };
  } catch (e: any) {
   return { error: handlePrismaError(e) };
  }
 };
}

console.log(
   "APP: Creating a new user",
   // Creating a new user
   await UserTable.create({
    email: "[email protected]",
    password: "password",
    phoneNumber: "+977-9000000012",
   })
  );

Prisma의 오류 처리

아래와 같이 try-catch 블록을 사용하여 오류를 처리할 수 있습니다.

try{
 ....
}catch(error){
 if(e instanceof PrismaClientKnownRequestError){
  ...
  // Do Something
  ...
 }
}

// Path: Tables\PrismaError.ts

import { PrismaClientKnownRequestError } from "@prisma/client/runtime";

export const handlePrismaError = (
 error: PrismaClientKnownRequestError
): string => {
 switch (error.code) {
  case "P2000":
   return `The ${error.meta?.column_name} is too long. `;
  case "P2001":
   return `No records found for the ${error.meta?.target}`;
  case "P2002":
   return `Unique constraint failed on the ${error.meta?.target}`;
  case "P2003":
   return `Foreign key constraint failed on the ${error.meta?.target}`;
  case "P2004":
   return `The ${error.meta?.target} already exists`;
  default:
   return "Something went wrong";
 }
};

보너스 팁

  • vs Code에서 확장 프로그램을 설치하면 Prisma코드 제안, 코드 서식 지정 등과 같은 기능에 액세스할 수 있습니다.
  • 명령을 사용하여 prisma 파일을 포맷할 수도 있습니다 yarn prisma format.
  • dev 서버에서 마이그레이션을 수동으로 트리거하려면 yarn prisma migrate dev명령을 사용하십시오.
  • yarn prisma -h명령을 사용하여 다른 prisma 명령을 알아낼 수 있습니다.