TIL 40 | ORM과 PRISMA

dabin *.◟(ˊᗨˋ)◞.*·2021년 9월 15일
0

Database

목록 보기
5/6
post-thumbnail

ORM(Object Relational Mapping)

Front-end는 자바스크립트만 사용할 수 있지만, Back-end는 언어도 많고 프레임워크도 많다. 이에 따라 언어별로 ORM 종류도 다양하며(예를 들어 typeORM(for typescript)) 문법도 조금씩 다르다. 하지만 기본적인 개념은 바뀌지 않아 하나를 잘 익히면 다른 것을 배울 때 쉽게 할 수 있다! 그러니 지금은 기본 동작 원리를 파악하는데 초점을 맞춰 공부하자.

ORM을 사용하면 해당 언어에 적합한 객체의 형태로 데이터를 반환해준다는 것을 기억하고, ORM Class와 Database table 사이의 매칭 관계를 살펴보자.

class Dog {
  constructor(name, owner, age){
    this.name = name;
    this.owner = owner;
    this.age = age;
  }
}

const darling = new Dog('달링이', '우니우니', 7)

이 class를 표로 그리고 그 관계를 파악해보자.

nameownerage
달링이우니우니7

테이블을 클래스라고 생각하고, 테이블의 column을 클래스의 속성으로 생각하고, 속성 아래 부터 하나의 행을 하나의 인스턴스라고 생각해보자. 비슷하다! 이렇게 테이블과 column, 그리고 행(데이터)를 클래스(객체)의 특성과 연관지어 사고하는 패러다임이 바로 ORM이다.

Prisma

Prisma는 Typescript와 Node.js 환경에서 데이터베이스에 대한 접근을 쉽게 할 수 있도록 도와준다. Prisma를 사용하는 이유 중 하나는 Typescript나 GraphQL을 사용할 수 있는 확장성이다. Prisma를 사용해서 raw query를 사용할 때보다 간편하게 데이터베이스의 테이블을 생성해보자.

먼저 알아둬야할 것은 데이터베이스는 결국 sql 문법만 알아 듣는다는 점이다. Prisma 문법으로 작성된 것은 변환 과정(migration)이 꼭 필요하다.

prisma를 사용하기 전에 협업을 위한 github 설정부터 했다.

  1. Git init : 깃 시작
  2. Git remote add origin 링크 : github와 연결
  3. npm init -y : npm 시작, 설정은 모두 yes!
  4. install packages(nodemon, babel, prisma & prism/client, express, eslint, bcrypt, jwt)
  5. npm start를 위해 package.json 수정
    "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "nodemon --exec babel-node src/server.js"
    }
  6. eslint & prettier 설정
  7. express 사용해 src/server.js 세팅 : open server

팀에서 설정

npm install prisma --save-dev
npm install @prisma/client --save

npm install dotenv nodemon -D

[.gitignore 설정]

  1. 리액트의 CRA와 달리 직접 작성해야한다. 아래 사이트에서 쉽게 작성한 뒤 복사-붙여넣기 할 수 있다.
  2. https://www.toptal.com/developers/gitignore

[Node.js에서 ES6 syntax 사용]

  1. npm install @babel/core @babel/node @babel/preset-env --save-dev nodemon
  2. 최상위 폴더에 .babelrc 생성 후 {"presets":["@babel/preset-env"]} 작성
  3. package.json의 script 부분 수정(위에 작성한 github설정 순서의 6)
  4. 그러나
    package.json에 type을 추가해주는 것만으로도 ES6 syntax를 사용할 수 있게 되었다.
    (node.js 버전에 따라 상이)
{
 	...(생략)
	"type": "module"
 	...(생략)
}

따로 설정

git clone 링크
git branch branch_name
git checkout branch_name
npm install

npx prisma init // prisma 초기 세팅

데이터베이스 연결

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

.env(환경변수 파일, 숨겨주기 필수!!)

DATABASE_URL = "mysql://USERNAME:PASSWORD@localhost:3306/DATABASE_NAME"

Migration

npx prisma migrate dev --name init

//migration을 하면 파일 이름이 11291037891_init과 같이 생성된다. 
//init을 상황에 따라 added_users와 같은 방식으로 작성하면 된다. 

Migration 과정은 models => migrations => database다. 이 과정을 상황에 따라 models -> migrations, migrations -> database로 분리할 수도 있다. migration만 하고 database를 변경하고 싶지 않을 때는 --create-only를 추가하여 migrate하면 된다. 이후 migrate dev로 database에 반영한다.

prisma 문법

빠르게 prisma 문법을 살펴보자.

datasource db {
  provider = "mysql"
  url      = env("DATABASE_URL")
}
-- DATABASE_URL은 .env에 저장해뒀다. 

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

model Category {
  id          Int             @id @default(autoincrement())
  name        String
  product    Product[]

  @@map("categories")
}

model Product {
  id           Int             @id @default(autoincrement())
  categoryId   Int             @map("category_id")
  koreanName   Int             @map("korean_name")
  englishName  String          @map("english_name")
  category     Category        @relation(fields: [categoryId], references: [id])
  image        Image[]
  nutrition    Nutrition?

  @@map("products")
}
...
  • model이 하나의 table이 된다고 생각하자. Category 표에서 생각했을 때, 그 안의 id, name, product는 표에서 각 column이 된다.
  • 각 column의 속성을 정해주는데, mysql문법과는 조금 다른 것을 알 수 있다. 예를 들어, VARCHAR은 prisma에서 String으로 사용되고 있으며 migration을 하면 VARCHAR(191)로 해석된다.
  • @id는 primary key를 지정하며, @map을 통해 migration 후의 name을 지정할 수 있다.
  • foreign key를 사용한 참조관계는 fk가 있는 model에 @relation을 설정하고, 참조되는 model에 그 관계를 명시하는 것이다.
  • 작성 후 migration을 하면 migrations 폴더가 생성되는데, 파일을 보면 INSERTO INTO~ 등의 raw query로 변환되어 있는 것을 확인할 수 있다.
  • backup 해둔 데이터를 복원하면 아래와 같이 표가 쫘란 하고 생성되어 있는 것을 확인할 수 있다.
//백업
mysqldump -u root -p databaseName > fileName.sql
//복원
mysql -u root -p databaseName < fileName.sql

profile
모르는것투성이

0개의 댓글