Node 강의/숙련

1-7 ORM과 Prisma(+ Posts 게시판 만들기 DB 밑 작업)

kagan-draca 2024. 9. 6. 19:33

1. Prisma 란?

 

PrismaORM(Object Relational Mapping)으로써

JavaScript 객체(Object)데이터베이스의 관계(Relation)연결(Mapping)해주는 도구입니다.

 

Node.js 환경에서는 TypeORM, Prisma, Sequelize 등 다양한 ORM이 존재합니다.

 

하지만, 우리는 JavaScript 뿐만 아니라 TypeScript에서도 사용할 수 있고,

ORM 개념을 학습하기 쉬운 Prisma를 배워볼 예정입니다.

 

2. Prisma vs Mongoose

 

Mongoose :

 

1. ODM(Object Document Mapping)으로 JavaScript 객체Document와 연결하지만,

 

2. mongoose지원하는 데이터베이스MongoDB 밖에 존재하지 않는다.

 

3. mongoose는 Schema의 형태컬렉션(Collection)에 대한 속성을 설정

 

Prisma :

 

1. ORM(Object Relational Mapping)으로 JavaScript의 객체데이터베이스관계(Relation)

    연결해주는 차이점이 있다.

 

2.  Prisma의 경우 RDBMS에 해당하는 다양한 데이터베이스사용할 수 있습니다.

 

3. Prisma는 Model의 형태테이블(Table)속성을 설정

 

3. Prisma와 같은 ORM을 사용하는 가장 큰 이유

 

1. 프로덕션에서 사용하는 데이터베이스가 언제바뀔지 알 수 없습니다.

 

    ORM을 도입하였을 경우 ORM의 속성값만 변경할 경우

    언제든지 자유롭게 DB를 변경할 수 있게 돼 개발할 때

    선택의 폭이 넓어지게 됩니다.

 

2. 데이터베이스에서 사용하는 DB 또는 Table 속성이 변경되었을 때 빠르게 수정이 가능합니다.

 

    ORM을 사용하였을 경우 테이블을 나타내는 Prisma의 model을 수정하기만 하더라도

    수많은 API에서 Raw Query를 수정하지 않고도 visibility Column 값에 대한 정보를 추가할 수 있다.

 

 

하지만, 이러한 장점을 가지고 있는 ORM도 만능은 아니다.

(ORM 단점)

 

JOINUNION 연산자동시에 사용하는 복잡한 쿼리를 작성할 경우,

ORM으로 구현하기 위해 SQL 보다는 QRM을 더 깊게 이해하야 하는 상황이 생긴다.

 

또한, 서브 쿼리를 포함하는 복잡한 쿼리를 작성하거나, ORM의 SQL로 변환해주는 시간 조차

아까운 극한의 성능을 요구하는 쿼리가 필요한 상황에서는 Raw Query를 사용하는 것이 더 좋다.

 

3. Prisma 시작하기

 

1) Prisma 라이브러리 설치하기

 

yarn init -y

# yarn 프로젝트를 초기화합니다.

 

yarn add express prisma @prisma/client

# express, prisma, @prisma/client 라이브러리를 설치합니다.

 

yarn add -D nodemon

# nodemon 라이브러리를 DevDependency로 설치합니다.

 

npx prisma init

# 설치한 prisma를 초기화 하여, prisma를 사용할 수 있는 구조를 생성합니다.

 

 

prisma는 우리가 Prisma터미널에서 사용할 수 있도록 도구를 설치하는 패키지입니다.

 

@prisma/client는 우리가 Node.js에서 Prisma를 사용할 수 있게 해줍니다.

 

nodemon은 개발 코드가 변경됐을 때 자동으로 서버 재시작을 해주는 패키지입니다.

 

디렉토리 구성
package.json 내구 구성

Prisma 폴더 안에 prisma.schema 파일 생성

 

- 이 파일은 Prisma가 사용할 데이터베이스를 설정하기 위해 사용하는 파일입니다.

 

(중요)Root 폴더에 .env 파일 생성됨

 

- 이 파일은 외부에 공유되어선 안 되는 비밀 정보들이 저장 돼 있는 파일 입니다.

 

(중요)Root 폴더에 .gitignore 파일 생성됨

 

- .env 파일이 git에 업로드되지 않도록 설정돼 있습니다.

 

 

주의!! 생성된 폴드나 파일들은 절대로 임의로 옮기지 말 것

임의로 옮기면 Prisma가 오동작 할 가능성이 높습니다.

 

 

2) nodemon 라이브러리는 뭔가?

 

nodemon파일을 저장할 때 마다 변경 사항을 감지하고,

자동으로 서버를 재시작해주는 라이브러리입니다.

개발 중 변경사항을 즉시 반영하여 개발 효율성을 향상시킬 수 있습니다.

 

nodemon 명령어

 

nodemon <실행할 JavaScript 파일명>

# 형식

 

nodemon app.js

# nodemon을 이용해 app.js 파일 실행하기

 

package.json nodemon 스크립트 등록하기

{
  "name": "Prisma_CRUD",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "type": "module",
  "scripts": {
    "dev" : "nodemon app.js"
  },
  "dependencies": {
    "@prisma/client": "^5.19.1",
    "express": "^4.19.2",
    "prisma": "^5.19.1"
  },
  "devDependencies": {
    "nodemon": "^3.1.4"
  }
}

 

  "scripts": {
    "dev" : "nodemon app.js"
  },

 

# 매번 명령어를 입력하지 않아도 간편하게 서버를 시작할 수 있다.

 

 

그 후, 터미널에서 yarn dev를 입력해줍니다.

 

3) schema.prisma

 

prisma.schema 파일은 Prisma가 사용할 데이터베이스의 설정 정보를 정의하기 위해 사용하는 파일입니다.

 

Prisma를 가장 처음 초기화 하였을 때, prisma.schema 파일을 확인한다면,

아래의 2가지 구문이 작성 돼 있는 것을 확인할 수 있습니다.

 

datasource

 

- 데이터베이스에 대한 정의를 하기 위해 사용됩니다.

- Prisma가 어떤 데이터베이스 엔진을 사용할 것인지,

  데이터베이스의 위치(URL)는 어디인지 등의 정보를

  정의하는데 사용됩니다.

 

generator

 

- Prisma 클라이언트를 생성하는 방식을 설정하는 구문입니다.

                         (수장하지 않을 것 입니다)

 

4) Prisma datasource

 

datasource는 Prisma가 데이터베이스를 연결할 수 있도록 설정하고,

관리하는 데 필요한 정보를 설정하는 구문입니다.

 

datasource 프로퍼티에 정의된 속성들을 수정하여

사용자 아이디, 비밀번호, 엔드 포트

다양한 설정 값을 입력해주어야 합니다.

 

datasource 설정하기

 

privoderPrisma가 사용할 데이터베이스 엔진의 유형

url : 데이터베이스를 연결하기 위한  URL

 

url 부분에서 env("DATABAESE_URL") 방식으로,

데이터베이스의 주소가 노출되지 않게 작성하는

dotenv의 문법을 사용하고 있습니다.

 

env는 .env 파일에 정의 돼 있는 정보를 schema.prisma 파일로 불러오는 것 입니다.

 

dotenv는 어플리케이션의 환경 변수(Environment Variables)관리하는 모듈입니다.

실제코드에서 민감한 정보를 노출시키지 않도록 보호해주고, 개발 환경에 따라 다르게

설정해야 하는 값을 별도의 파일에서 관리할 수 있게 해줍니다.

 

.env 파일 확인하기

# Environment variables declared in this file are automatically made available to Prisma.

# 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="postgresql://johndoe:randompassword@localhost:5432/mydb?schema=public"

 

.env 파일은 Key - Value의 형태로 구성돼 있고,

DATABASE_URL이라는 하나의 변수선언

있는 것을 확인할 수 있습니다.

 

DATABASE_URL값을 변경해서 연결하고자 하는 DB를 연결할 수 있습니다.

 

데이터베이스 URL

 

URL의 내부에는 데이터베이스 엔진 유형, 사용자 아이디, 패스워드와 같은 정보가 포함됩니다.

 

 

Protocal

 

- Prisma가 사용할 데이터베이스 엔진을 나타냅니다.

-postgresql, sqlite, mysql 과 같은 데이터베이스 엔진을 정의합니다.

 

Bse URL

 

- 데이터베이스의 엔드 포인트아이디, 패스워드, 비밀 번호를 나타냅니다.

- <Id> : <Password>@<RDS Endpoint>:<Port>의 형태로 구성됩니다.

 

Path

 

MySQL에서 사용할 데이터베이스 이름을 설정하는 구성 요소

 

Arguments

 

- Prisma에서 데이터베이스 연결을 설정하는데 필요한 추가 옵션을 나타냅니다.

- 데이터베이스와 연결할 수 있는 최대 커넥션 갯수, 타임아웃 시간 등이 있습니다.

 

Prisma의 데이터베이스 URL 구현하기!

 

저희가 대여받은 RDS의 속성값은 아래와 같습니다. 여러분들이 대여받은 RDS의 속성값을 바탕으로 데이터베이스 URL을 구성해주세요!

  • 데이터베이스 엔진: mysql
  • 마스터 사용자 이름: root
  • 마스터 암호: aaaa4321
  • RDS 엔드포인트: express-database.clx5rpjtu59t.ap-northeast-2.rds.amazonaws.com
  • Port 번호: 3306
  • 사용할 DB 이름: prisma_crud

예상 정답 : 

mysql://root:aaaa4321@express-database.clx5rpjtu59t.ap-northeast-2.rds.amazonaws.com:3306/prisma_crud

 

정답 : 

mysql://root:aaaa4321@express-database.clx5rpjtu59t.ap-northeast-2.rds.amazonaws.com:3306/prisma_crud

 

5) Prisma model

 

Prismamodel 구문은 특정 TableColumn의 속성값입력하여,

데이터베이스와 Express 프로젝트를 연결(Mapping)시켜줍니다.

 

model 구문은 Prisma를 사용할 때 가장 많이 작성하게 될 구문으로,

데이터베이스의 테이블 구조를 정의하기 위해 사용합니다.

 

schema.prisma 파일에서는 model에 작성된 정보를 바탕으로 Prisma Client를 통해

JavaScript에서 MySQL의 테이블을 조작할 수 있게 됩니다.

 

model 구문은 JavaScript에서 MySQL의 테이블을 사용하기 위한 다리 역할을 수행하며,

MySQL과 실제 연결 돼 사용할 수 있게 됩니다.

 

 

ex) 상품(Products)을 담당하는 테이블 구현해보기

 

model Products{
  productId Int @Id @default(autoincrement()) @map("productId")
  productName String @unique @map("priceName")
  price Int @default(1000) @map("price")
  info String? @map("info") @db.Text

  createAt DateTime @default(now()) @map("createAt")
  updateAt DateTime @updateAt @map("updateAt")

  @@map("Products")
}

(중요)모든 따옴표는 "(쌍따옴표)로 작성 돼야 한다.

 

 

데이터 유형으로는 Int, String, DateTime이 있는 것을 확인할 수 있습니다.

 

데이터 유형 뒤 ?NULL 허용 가능을 의미합니다.

                (? 가 없다면 NOT NULL)

 

 

제약조건으로는PRIMARY KEY, UNIQUE, AUTO_INCREMENT가 보입니다.

 

PRIMARY KEY : @Id

 

AUTO_INCREMENT : @defualt(autoincrement())

 

UNIQUE : @unique

 

@@map("Products")는 Products 테이블을 MySQL에서도 Products란 이름으로 사용하겠다는 뜻

 

@@map()을 작성하지 않으면, 테이블명의 대문자는 전부 소문자로 치환됩니다.

 

Prisma schema로 작성된 코드가 위와 같은 형태로 구현될 겁니다.

 

이번에는 게시글(Posts) 테이블을 정의해주세요.

 

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

// Looking for ways to speed up your queries, or scale easily with your serverless or edge functions?
// Try Prisma Accelerate: https://pris.ly/cli/accelerate-init

generator client {
    provider = "prisma-client-js"
  }
 
  datasource db {
    provider = "mysql"
    // MySQL 데이터베이스 엔진을 사용합니다.
 
    url      = env("DATABASE_URL")
    // 데이터베이스 연결 정보를 .env 파일의
    // DATABASE_URL로부터 읽어옵니다.
  }
 
  model Posts {
    postId    Int      @id @default(autoincrement()) @map("postId")
    title     String   @map("title")
    content   String   @map("content") @db.Text
    password  String   @map("password")
    createdAt DateTime @default(now()) @map("createdAt")
    updatedAt DateTime @updatedAt @map("updatedAt")
 
    @@map("Posts")
  }

 

위와 같이 명세표를 바탕으로 정의할 수 있습니다.

 

이제 만들어진 Posts 테이블 정의를 바탕으로

테이블과 Colum을 생성해보겠습니다.

 

4. Prisma DB, Table 생성하기

 

터미널에 

npx prisma db push

# schema.prisma 파일에 설정된 모델을 바탕으로 MySQL에 정보를 업로드 합니다.

 

입력해줍니다.

 

 

그럼 

위와 같은 문구와 함께,

 

 

"express_db"에 Posts 테이블과 Colum이 생성됩니다.

 

5. Prisma CLI 알아보기

 

1) prisma db push

 

- schema.prisma 파일에 정의된 설정값을

  실제 데이터베이스반영(Push)합니다.

- 내부적으로 prisma generate가 실행됩니다.

- 데이터베이스 구조를 변경하거나 새로운 테이블을 생성합니다.

 

2) prisma init

 

- Prisma를 사용하기 위한 초기 설정을 생성합니다

- 대표적으로, schema.prisma 파일에 변경 사항이 생겼거나,

  데이터베이스 구조가 변경되었을 때, 이 명령어를 사용해

  Prisma Client를 최신 상태로 유지할 수 있습니다.

 

3) prisma generate

 

- Prisma Client를 생성하거나 업데이트 합니다.

- 대표적으로, schema.prisma 파일에 변경 사항이 생겼거나,

  데이터베이스 구조가 변경 되었을 때, 이 명령어를 사용해

  Prisma Client를 최신 상태로 유지할 수 있습니다. 

 

3) prisma db pull

- 현재 연결된 데이터베이스의 구조prisma.schema 파일로 가져니다(pull)

- 데이터베이스에서 구조 변경이 발생했을 때, 이 명령어를 사용하면 Prisma Schema를 최신 상태로 유지할 수 있습니다.

- 이후 prisma generate 명령어를 사용해 변경 사항을 Prisma Client에 반영할 수 있습니다.

 

이외에도 다양한 명령어가 존재합니다.

 

6. Prisma Client

 

Prisma는 model을 generate하면, 해당 모델에 대한 정보가

node_modules 폴더 내에 있는 Prisma Client에 전달됩니다.

 

→ prisma db push도 내부적으로 generate가 실행됩니다.

 

Prisma ClientPrisma Schema에 정의한 데이터베이스 모델(model)TypeScript 코드로 변환하여,

개발자가 데이터베이스와 상호작용할 수 있게 해줍니다.

 

이러한 과정을 통해, 데이터베이스를 JavaScript에서 손쉽게 다룰 수 있게 되고,

Prisma Schema동기화된 Prisma Client를 이용해 데이터베이스를 사용할 수 있게 됩니다.

 

6. Prisma Clinet 구성 확인하기

// node_modules/.prisma/client/index.d.ts

  export type $PostsPayload<ExtArgs extends $Extensions.InternalArgs = $Extensions.DefaultArgs> = {
    name: "Posts"
    objects: {}
    scalars: $Extensions.GetPayloadResult<{
      postId: number
      title: string
      content: string
      password: string
      createdAt: Date
      updatedAt: Date
    }, ExtArgs["result"]["posts"]>
    composites: {}
  }

  type PostsGetPayload<S extends boolean | null | undefined | PostsDefaultArgs> = $Result.GetResult<Prisma.$PostsPayload, S>

 

- schema.prisma 파일에 정의한 내용과 같이,

  Products 테이블에 대한 내용이 위와 같이 작성됩니다.

 

- 저희가 Prisma를 이용하여 데이터베이스를 조작할 때

  이러한 Prisma Client로 사용하게 되는 것 입니다.

'Node 강의 > 숙련' 카테고리의 다른 글

1-9 쿠키와 세션  (0) 2024.09.07
1-8 Prisma Method(+Posts 게시판 만들기 서버와 DB 연결)  (0) 2024.09.07
1-6 Raw Query시작하기  (0) 2024.09.06
1-5 SQL 제약조건  (0) 2024.09.05
1-4 SQL (Structured Query Language)  (0) 2024.09.05