7. Prisma
이번 시간에는 Node.js & TypeScript의 ORM 중 하나인 Prisma에 대해 알아봅시다.
공부할 내용 📚
1. Prisma가 무엇인가요?
ORM…?? ORM은 뭐고, Prisma는 또 무엇일까요?
ORM의 의미와, Prisma가 어떤 서비스인지 한 번 알아봅시다!
- ORM이 뭘까?: ORM이 뭔지 간단히 알아봅시다!
- 이외에도 구글링하면 ORM에 대해서 많은 정보들이 나오니 참고해주세요! 😀
- Is Prisma an ORM?: Prisma 공식문서에서 Prisma가 무엇인지, 어떤 원리로 작동되는지에 대해서 간단히 소개해줍니다.
- Prisma란?: 한글로도 짧게 정리한 블로그 글도 가져와봤습니다!
2. Prisma
이제 ORM이 무엇이고, Prisma는 어떤 서비스인지 알아보았으니 구체적으로 어떻게 사용할 수 있는지 알아볼까요?
- What is Prisma?: Prisma의 작동 원리에 대해서 알아봅니다. 꼭 읽어봐주세요!! ⭐️
- Prisma schema: Prisma는 schema 파일을 통해 다양한 설정 정보를 얻고 어떠한 데이터 모델을 생성할지 파악합니다. schema 파일이 어떻게 구성되어 있고, 데이터 모델은 어떻게 작성할 수 있는지 살펴봐야겠죠? 😆
- Prisma CRUD: Prisma에서는 아주 많은…. 기능들이 있는데요, 이번에는 그중 실습때 쓰이는 CRUD관련 기능만 살펴봐주세요 🙂
- Prisma Playground: Prisma에서는 Playground를 통해 웹에서도 테스트할 수 있도록 해줘요! Playground를 통해 한 번 테스트해봐도 좋아요!
- Prisma Client API reference: API reference인데, 궁금하신 부분있으면 찾아봐도 괜찮을 것 같아요!
프로젝트 실습 🎈
이번 주차는 저번 주차에서 만들었던 Nest.js 웹서버에서 실제 데이터베이스(PostgreSQL)에 prisma를 이용하여 CRUD 코드를 작성해보는 과제입니다.
환경 설정 관련해서 아래 지시사항을 따라해주세요! 물론 꼭 그대로 따라하실 필요는 없고 자신의 데이터 구조에 따라 바꾸셔도 괜찮습니다!
실습 세부 설명 ⚙️
환경세팅과 관련해서 도와드릴게요! 밑의 절차를 따라와주세요
참고 : https://www.prisma.io/blog/nestjs-prisma-rest-api-7D056s1BmOL0
시작 전, Docker 설치 가이드를 참고하여 Docker를 설치해주세요!
Root 디렉토리에 docker-compose.yml
를 생성하고, 아래 파일을 복사-붙여넣기 해주세요.
# docker-compose.yml
version: '3.8'
services:
postgres:
image: postgres:13.5
restart: always
environment:
- POSTGRES_USER=myuser
- POSTGRES_PASSWORD=mypassword
volumes:
- postgres:/var/lib/postgresql/data
ports:
- '5432:5432'
volumes:
postgres:
그 뒤, 터미널에서 docker-compose up -d
을 실행하고(-d
는 백그라운드에서 실행하는 옵션) , 정상적으로 컨테이너가 생성되고 실행되는지 확인해주세요
- 터미널에 Running 표시 혹은 docker gui 에서 실행되고 있다면 성공입니다
- 🛠️ 백그라운드에서 정상적으로 작동해야지 밑의 과정에서 오류가 생기지 않습니다!
다음으로 터미널에 npm install -D prisma
을 입력해 prisma 를 설치해줍니다.
루트 디렉토리에서 npx prisma init
를 입력하면, prisma 폴더와 Schema 파일이 생성된 것을 확인할 수 있습니다.
루트 폴더에 .env 파일이 생성되었는 것을 볼 수 있는데요, 안에는 database_url 이 들어있을 건데 밑과 같이 변경해줍니다.
// .env DATABASE_URL="postgres://myuser:mypassword@localhost:5432/median-db"
prisma/schema.prisma
에 들어가 맨 밑에 restaurant model 을 추가해줍시다!
자신의 데이터구조에 맞게 자유롭게 작성해주시면 됩니다! 제가 작성한 예시를 남겨드립니다.
// 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 = "postgresql" url = env("DATABASE_URL") } model Restaurant { id Int @id @default(autoincrement()) name String @unique address String phone String createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
다음, 우리가 생성한 데이터 모델을 migrate하기 위해 아래 명령어를 입력해줍니다.
npx prisma migrate dev --name "init"
- 성공적으로 되었다면 terminal에
Your database is now in sync with your schema
라는 문장과 함께prisma
안에migration
폴더가 생성되는 것을 확인할 수 있어용
원활한 테스팅을 위해 데이터베이스에 미리 seed 데이터도 심어놓읍시다.
- 아래
seed.ts
를 생성해주세요! (데이터 구조는 자신의 것과 일치하게 수정해주셔도 됩니당)
// prisma/seed.ts
import { PrismaClient } from '@prisma/client';
// initialize Prisma Client
const prisma = new PrismaClient();
async function main() {
// create two dummy articles
const restaurant1 = await prisma.restaurant.upsert({
where: { name: '봉수육' },
update: {},
create: {
name: '봉수육',
address: '경기 수원시 장안구 율전로108번길 11 1층',
phone: '0507-1460-0903',
},
});
const restaurant2 = await prisma.restaurant.upsert({
where: { name: '청년밥상' },
update: {},
create: {
name: '청년밥상',
address: '경기 수원시 장안구 서부로2136번길 10 1층',
phone: '0507-1307-1822',
},
});
console.log({ restaurant1, restaurant2 });
}
// execute the main function
main()
.catch((e) => {
console.error(e);
process.exit(1);
})
.finally(async () => {
// close Prisma Client at the end
await prisma.$disconnect();
});
그리고 package.json
에 아래 명령어를 추가해주세요.
// package.json
// ...
"scripts": {
// ...
},
"dependencies": {
// ...
},
"devDependencies": {
// ...
},
"jest": {
// ...
},
**"prisma": {
"seed": "ts-node prisma/seed.ts"
}**
그리고 터미널에 npx prisma db seed
를 입력해주시면 귀여운 새싹모양 아이콘이 뜰거에요ㅎ.ㅎ
prisma를 연결해주기 위해
npx nest generate module prisma
npx nest generate service prisma
를 입력해주시고, prisma.service.ts
파일을 조금 수정해줍니다.
// src/prisma/prisma.service.ts
import { INestApplication, Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class PrismaService extends PrismaClient {
async enableShutdownHooks(app: INestApplication) {
this.$on('beforeExit', async () => {
await app.close();
});
}
}
그리고 prisma.module.ts
도 수정해줍니다. (exports에 추가)
// src/prisma/prisma.module.ts
import { Module } from '@nestjs/common';
import { PrismaService } from './prisma.service';
@Module({
providers: [PrismaService],
exports: [PrismaService],
})
export class PrismaModule {}
마지막으로 저희 Restaurant 모듈에서 쓰기 위하여 service, module 파일을 조금 수정해주세요!
- 밑에는 예시 코드입니다.
//restaurant.module.ts
import { Module } from '@nestjs/common';
import { PrismaModule } from 'src/prisma/prisma.module';
import { RestaurantController } from './restaurant.controller';
import { RestaurantService } from './restaurant.service';
@Module({
controllers: [RestaurantController],
providers: [RestaurantService],
imports: [PrismaModule],
})
export class RestaurantModule {}
//restaurant.service.ts
import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
@Injectable()
export class RestaurantService {
constructor(private prisma: PrismaService) {}
//example
async getAllRestaurants() {
return await this.prisma.restaurant.findMany({
select: {
name: true,
address: true,
phone: true,
},
});
}
}
이제 직접 CRUD 코드를 작성하면 됩니다. 😆
- 참고로,
npx prisma studio
를 입력하면 5555포트에서 정말 간편하게 db 를 눈으로 확인할 수 있으니 애용해주세요 😻