-
Prisma - 🐠시작하기 환경설정, 쿼리 로깅, CRUDFrameWork/ORM 2024. 4. 12. 10:52
Prisma 설정하기
[Quickstart]
https://www.prisma.io/docs/getting-started/quickstart
nodeJs-express 서버에서 prisma 사용하기
prisma 의존성 설치
yarn add prisma --dev
prisma init
npx prisma init
이후 생성되는 파일과 폴더
Prisama로 DB와 연결하고 마이그레이션
prisma/schema.prisma 파일에 정의된 스키마
// 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" url = env("DATABASE_URL") } enum ArticleState{ DRAFT PUBLISHED } model Article{ id Int @id @default(autoincrement()) title String content String state ArticleState createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
마이그레이션 명령어
dotenv -e .env.local -- npx prisma migrate dev
로컬에서 이러한 마이그레인셔을 실행할려고 하면 위 명령어를 사용하는 것이 좋다. 왜냐하면 이 명령어는 shadow 데이터베이스를 생성하고 그것에서 모든 마이그레이션을 실행하려고 시도한다. 이때 뭔가 실패하면 오류 메시지가 표시된다. 그리고 모든 것이 성공적으로 작동한다면 실제환경에서 마이그레이션이 실행된다. 하지만 해당 명령은 프로덕션 환경에서는 권장 되지 않으므로 proudct서버에서는 사용하지 않는 것이 좋다.
즉 위 명령어는 개발 중에 오류를 파악하기 위한 개발 중에 사용하기 적절한 명령어이다.
Enter a name for the new migration > CreateArticlesTable // 마이그레이션 이름을 묻는다.
그러고 나면 테이터과 스키마가 동기화 되었다는 뜻의 콘솔이 출력된다.
마이그레이션을 사용하는 이유
Article 테이블 명을 → articles로 마이그레이션하기
schema.prisma
model Article{ id Int @id @default(autoincrement()) title String content String state ArticleState createdAt DateTime @default(now()) updatedAt DateTime @updatedAt @@map("articles") }
마이그레이션 명령어
dotenv -e .env.local -- npx prisma migrate dev
마이그레이션으로 추적 가능해진 테이블의 변화
/* Warnings: - You are about to drop the `Article` table. If the table is not empty, all the data it contains will be lost. */ -- DropTable DROP TABLE `Article`; -- CreateTable CREATE TABLE `articles` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `title` VARCHAR(191) NOT NULL, `content` VARCHAR(191) NOT NULL, `state` ENUM('DRAFT', 'PUBLISHED') NOT 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;
prisma 폴더 하위를 살펴보면 그동안 npx prisma migrate dev 명령어를 사용해서 생성된 쿼리를이 저장되어 있는 것을 확인할수 있다. Article 테이블을 articles 테이블로 이름을 수정할 때 생성된 쿼리도 확인할 수 있다.
마이그레이션을 사용하면 테이블에 대한 변경사항도 git을 통해 추적할 수 있다. 그래서 테이블의 칼럼을 추가하거나 Type의 변경 데이터베이스 구조와 관련된 모든 변경 사항은 마이그레이션을 통해 수행되면 체계적으로 관리할 수 있다. 협업을 하는 경우 데이터베이스를 모든 팀과 동기화 하는 것에도 도움이 된다.
Prisma를 사용하는 CRUD
Prisma 클라이언트 인스턴스화
Prisma 클라이언트 설치
yarn add @prisma/client
위 모듈이 설치되면 Prisma는 클라이언트를 인스턴스화 하게된다. 프리즈마 클라이언트는 DB와 상호작용하면서 prisma가 수행해야하는 모든 쿼리를 만들고 수행한다.
Prisma 클라이언트 인스턴스 생성
import express from "express" import * as dotenv from 'dotenv' process.env.NODE_ENV == 'prod'? dotenv.config({path:'./.env.prod'}) : dotenv.config({path:'./.env.local'}); import bodyParser from "body-parser"; import { PrismaClient } from "@prisma/client" const app = express() const prisma = new PrismaClient() app.use(bodyParser.json())
article 데이터 생성
코드에 prisma. 만 입력해도 자동완성 추천 항목에 article이 제안되는 것을 확인할 수 있다.
Prisma를 이용한 create 코드
하나의 articles 생성하기
app.post('/articles', async (req, res) =>{ await prisma.article.create({ data : req.body }); res.json({success:true}); });
여러개의 articles 동시에 생성하기
app.post('/multiple-articles', async (req, res) =>{ await prisma.article.createMany({ data: req.body }); });
Prisma 쿼리 로깅하기
ORM이라는 이름에서 알수 있듯이 ORM을 사용하면 로우 SQL을 작성하는 것 대신 객체의 상호작용으로 이것을 다루면 훨씨 간단하고 단순해진다.
로깅 설정
const prisma = new PrismaClient({ log:["query"] })
ORM을 통한 메서드가 생성하는 SQL을 검증하려는 경우 new PrismaClient()를 사용해 Prisma 클라이언트를 인스턴스화 한 것을 활용하면 된다. 이 인스턴스를 생성시 몇가지 설정사항을 전달할 수 있다.
로깅 내용
위 설정 사항을 설정하고 나서 post './articles'를 실행하면 해당 해당 메소드가 작동하면서 실행된 쿼리가 기록된다. 따라서 prisma ORM 이 제공하는 메소드를 사용하면서 실제 실행된 쿼리를 제대로 추적하고 디버깅할 수 있게된다.
Prisma를 이용한 article 검색
모든 article 검색
app.get('/articles', async(req,res) =>{ //1.모든 기사 검색하기 const articles = await prisma.article.findMany(); res.json(articles); })
findMnay()는 where절 없이도 많은 작업을 수행할 수 있다. 즉 모든 article이 검색되고 반환된다.
특정 article 하나만 검색
app.get('/articles/:id', async(req,res) =>{ //2.특정 기사 하나 검색 const article = await prisma.article.findFirst({ where: { id: +req.params.id } }) res.json(article); })
여기서는 findFirst()메서드를 사용한다. 해당 메서드의 조건에 넣는ID와 일치하는 첫번째 레코드를 가져온다.
특정 조건에 부합하는 article 검색
app.get('/articles', async(req,res) =>{ //3.특정 조건에 부합하는 기사들 검색 //(fetch all article in draft state) const articles = await prisma.article.findMany({ where:{ state:req.query.state } }); res.json(articles); });
Prisma를 이용한 update 코드
updateMany 메소드
app.put('/articles/:ids', async(req, res) =>{ const idList = req.params.ids.split(',').map(id => +id); const updatedCount = await prisma.article.updateMany({ where:{ id:{ in : idList } }, data:{ title: req.body.title } }); res.json(updatedCount); });
위 코드에서 updateMany의 결과로 반환되는것은 update결과가 아니라 update된 레코드의 숫자이다.
upsert메소드
upsert()메소드가 updateMany()메소드와 다른점은 데이터베이스에 해당 조건의 레코드가 있으면 해당 레코드를 update하고 없을 경우는 새로 생성하는 것이다.
Prisma를 이용한 delete 코드
특정 article 삭제
app.delete('/articles/:id', async (req,res) =>{ const deleted = await prisma.article.delete({ where:{ id: +req.params.id } }); res.json(deleted); })
모든 article 삭제
//await prisma.article.deleteMany({});
where절로 별다른 조건을 지정하지 않고 deleteMany()를 실행하면 테이블의 모든 레코드가 삭제되므로 사용할때는 주의를 기울인다.
[출처 - Building Production-Ready Apps with Prisma Client for NodeJS, Naimish Verma]
'FrameWork > ORM' 카테고리의 다른 글
Prisma - Transactions과 다양한 부가기능 (0) 2024.04.17 Prisma - 객체 간의 관계 설정, 1:N, 1:1, N:M (0) 2024.04.16 Sequelize - 시퀄라이즈 시작 (설정,모델만들기,관계설정) (0) 2024.03.21 ORM - 영속성 관리(플러시, 준영속) (1) 2024.02.29 ORM - 영속성 관리(엔티티 등록,수정,삭제) (0) 2024.02.29