본문 바로가기
개발 기초 다지기

ORM과 Prisma 그리고 model 만들기

by 너의고래 2024. 5. 29.
반응형

이번 개인 과제를 진행하며 사용한 mysql 데이터베이스를 조작하는데 사용한 Prisma와 그 model 구현한 내용을 정리해보려한다.

 

ORM(Object-Relational Mapping)

: 객체 지향 프로그래밍 언어를 사용하여 관계형 데이터베이스를 조작할 있게 해주는 기술

 ORM 데이터베이스 테이블과 객체 지향 프로그래밍의 클래스를 매핑(mapping)하여, SQL 직접 작성하지 않고도 데이터베이스 작업을 수행할 있게 해준다. 이는 개발자의 생산성을 높이고, 데이터베이스와 애플리케이션 코드 간의 불일치를 줄이는 도움을 준다.

 

ORM은 여러가지의 관계형 데이터베이스(RDB)를 사용할 수 있다. (ex)MySQL,Oracle, MariaDB, PostgreSQL 등

 

Prisma

 ORM으로써 Javascript 객체(Object) 데이터베이스의 관계(Relation) 연결(Mapping) 해주는 도구

 

Prisma 같은 ORM 사용하는 가장 이유

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

ex) MySQL을 사용하다가 기술지원을 위해 Oracle로 바꿔야하는 경우,

  • 서비스 중인 프로덕션의 모든 Raw Query코드를 MySQL에서 Oracle로 변경
  • 또는 그냥 힘들어도 계속 쓰기

하지만, ORM 도입하였을 경우 단순히 ORM 속성값만 변경할 경우 자유롭게 DB 변경할 있어 개발할 선택의 폭이 넓어진다.

 

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

DB를 사용하는 코드를 모두 Javascript에서 Raw Query로 구현하였다고 가정시 불가피하게 수정이 발생할 경우,

단순히 한 부분이 아니라 해당하는모든 API를 해당하는 쿼리에 맞게 수정해야하는 불상사가 발생

(사용하는 API가 수십, 수백개가 된다고 했을 때 모든 코드를 수정하는 것이 쉽지 않음)

-> 여기서 ORM 사용하였을 경우 테이블을 나타내는 Prisma model 수정하기만 하더라도 수많은 API에서 Raw Query 수정하지 않아도 원하는 대로 수정 가능.

 

 

Prisma model

: 특정 Table Column 속성값을 입력하여, 데이터베이스와 Express 프로젝트를 연결 (Mapping)

 

  • Prisma가 사용할 데이터베이스의 테이블 구조를 정의하기 위해 사용됨
  • schema.prisma 파일에서는 model에 작성된 정보를 바탕으로 Prisma Client를 통해 JavaScript에서 MySQL의 테이블을 조작할 수 있게 됨
  • model 구문은 Javascript에서 MySQL 테이블을 사용하기 위한 다리 역할을 수행하며, MySQL 실제 연결되어 사용할  있게 도와줌

 

아래는 내가 이번 과제를 하며 구현해낸 모델구문이다.

enum UserRole {
  APPLICANT
  RECRUITER
}

model Users {
  userId Int @id @default(autoincrement()) @map("userId")
  email String @unique @map("email")
  password String @map("password")
  name String @map("name")
  role UserRole @default(APPLICANT)
  createdAt DateTime @default(now()) @map("createdAt")
  updatedAt DateTime @updatedAt @map("updatedAt")

  resumes Resumes[]

  @@map("Users")
}

 

데이터베이스의 Users 테이블과 연결시켜주는 Users model이다.

  • userId
    • 숫자 타입 - Int
    • @id로 기본키 지정
    • 'autoincrement()'를 default 값으로 주어 따로 입력하지 않아도 자동으로 ID값이 생성되도록 설정
    • @map을 통해 데이터베이스 상에서 저장될 이름을 지정
  • email
    • 문자 타입 - String
    • email은 중복되면 안되는 고유한 것이기에  @uniqe 사용
  • role
    • 타입을 enum로 설정해 정해진 선택지중에 선택하도록 설정
    • enum 위로 빼줘서 model의 통일성을 해치지 않도록 함
    • default를 통해 처음 생성시 'APPLICANT'로 데이터가 들어가도록 함
  • createdAt
    • datetime을 통해 날짜와 시간 형식 적용
    • default 값에 now()를 넣어주어 생성될 때의 시간을 넣어줌
  • updatedAt
    • datetime을 통해 날짜와 시간 형식 적용
    • 자동으로 수정될 시간을 넣어주는 내장된 기능인 @updatedAt 사용
  • 그 외 모두 유사
  • @@map("User") 
    • 데이터베이스에 저장될 테이블 이름 지정

 

 

 

enum ResumeStatus {
  APPLY
  DROP
  PASS
  INTERVIEW1
  INTERVIEW2
  FINAL_PASS
}

model Resumes {
  resumeId Int @id @default(autoincrement()) @map("resumeId")
  userId Int @map("userId")
  title String @map("title")
  content String @map("content") @db.Text
  status ResumeStatus @default(APPLY)
  createdAt DateTime @default(now()) @map("createdAt")
  updatedAt DateTime @updatedAt @map("updatedAt")

  user Users @relation(fields: [userId], references: [userId], onDelete: Cascade)

  @@map("Resumes")
}

 

데이터베이스의 Resume 테이블과 연결시켜주는 Resume model이다. (User model과 유사)

  • resumeId
    • 숫자 타입 - Int
    • @id로 기본키 지정
    • 'autoincrement()'를 default 값으로 주어 따로 입력하지 않아도 자동으로 ID값이 생성되도록 설정
    • @map을 통해 데이터베이스 상에서 저장될 이름을 지정
  • userId
    • 관계를 지정할 때 사용할 userId
    • 1:1 관계가 아니기 때문에 따로 @unique는 필요 없음
  • title
    • 문자 타입 - String
    • email은 중복되면 안되는 고유한 것이기에  @uniqe 사용
  • content
    • 기본적으로 제공하는 type이 아닌 다른 타입을 직접적으로 지정을하고 싶을 때 @db 사용
      text 타입이기 때문에 앞쪽에는 String으로 지정해준 후 뒤에 @db.Text로 텍스트 형식을 따로 만들어줌
  • status
    • 타입을 enum로 설정해 정해진 선택지중에 선택하도록 설정
    • enum을 위로 빼줘서 model의 통일성을 해치지 않도록 함
    • default를 통해 처음 생성시 'APPLY'로 데이터가 들어가도록 함
  • createdAt
    • datetime을 통해 날짜와 시간 형식 적용
    • default 값에 now()를 넣어주어 생성될 때의 시간을 넣어줌
  • updatedAt
    • datetime을 통해 날짜와 시간 형식 적용
    • 자동으로 수정될 시간을 넣어주는 내장된 기능인 @updatedAt 사용
  • 그 외 모두 유사
  • @@map : 데이터베이스에 저장될 테이블 이름 지정

 

model이 두개밖에 되지 않기 때문에 복잡하지는 않았다. 하지만 enum, @db.Text와 같은 부분이 완벽히 이해를 한 것 같지는 않아 추후 따로 공부가 필요하다고 느낀다.

 

 

추가로 내 과제에 구현하지 않은 다른 부분

  • String? : 데이터 유형 뒤에 ?가 붙게 된다면, NULL을 허용하는 컬럼 (->Optional Parateters)
* Prisma CLI

1) prisma db push
- schema.prisma 파일에 정의된 설정값을 실제 데이터베이스에 반영(push)
- 내부적으로 prisma generate가 실행
- 데이터베이스 구조를 변경하거나 새로운 테이블을 생성할 수 있음

2) prisma init
- Prisma를 사용하기 위한 초기 설정을 생성
- 이 명령어를 실행하면 schema.prisma 파일과 같은 필요한 설정 파일들이 생성됨

3) prisma generate
- Prisma Client를 생성하거나 업데이트
- 대표적으로, schema.prisma 파일에 변경 사항이 생겼거나, 데이터베이스 구조가 변경되었을 때, 이 명령어를 사용해 Prisma Client를 최신 상태로 유지

4) prisma db pull
- 현재 연결된 데이터베이스의 구조를 prisma.schema 파일로 가져옴 (pull)
- 데이터베이스에서 구조 변경이 발생했을 때, 이 명령어를 사용하면 Prisma Schema를 최신 상태로 유지할 수 있음
- 이후 prisma generate 명령어를 사용해 변경 사항을 Prisma Client에 반영할 수 있음

 

 

이전 단계에서 진행한 ERD 작성덕분에 스키마 모델은 쉽게 구현해낼 수 있었다. 아직 가볍게 이해한 단계기 때문에 추가적인 CLI 같은 경우는 미흡한 단계지만, 그래도 데이터베이스를 조종할 수 있게 되었다는 점에서 뭔가 뿌듯해진 기분이다. 데이터베이스 마스터가 되는 그 날까지 파이팅!

반응형

댓글