HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
💌
JJong’s Archive
/
Prisma ORM

Prisma ORM

날짜
Dec 12, 2024 09:56 AM
Prisma ORM(Object-Relational Mapping)
: Node.js에서 사용 가능한 ORM
ORM이란?
데이터베이스와 상호작용할 때 SQL 쿼리가 아닌, 프로그래밍 언어(js에선 객체)로 테이블의 데이터를 처리 가능하게 하는 프로그래밍 기술
  • 타입 안전함. 즉, 코드를 짤 때 데이터 타입을 가이드 해줌
간단 ex)
// 매핑 정의 model User { id Int @id @default(autoincrement()) name String @unique email String? @unique } // 객체로 데이터 조작 const user = await prisma.user.create({ data: { name: "John", email: "john@example.com" }, }); // name, email의 타입을 확인 가능

Prisma의 주요 구성 요소

  1. Prisma Client : 데이터에 맞춰 자동 생성되는 타입안전 쿼리 빌더
  1. Prisma Migrate : 데이터베이스 - 스키마 동기화
migrations폴더 생성 후, (SQL 코드로 바뀐)동기화 한 파일 생성 + database.db 생성or수정
migrations폴더 생성 후, (SQL 코드로 바뀐)동기화 한 파일 생성 + database.db 생성or수정
  1. Prisma Studio : CRUD를 로컬에서 시각적으로 할 수 있음
 

Prisma의 특징

  1. 서버컴포넌트에서만 사용 가능
  1. 타입 안전성:
      • Prisma Client는 타입스크립트를 기반으로 자동 생성되며, 데이터 모델에 따라 타입이 자동으로 정의됨
  1. 생산성 향상
      • 간단하고 직관적인 API로 데이터베이스 작업을 빠르게 처리가능
  1. 다중 데이터베이스 지원
      • MySQL, PostgreSQL, SQLite, MongoDB 등 다양한 데이터베이스를 지원
  1. 마이그레이션 관리:
      • Prisma Migrate를 통해 데이터베이스 스키마 변경 작업을 체계적으로 관리할 수 있음
  1. 데이터 정합성 보장
      • 관계형 데이터베이스의 관계를 쉽게 정의하고 관리할 수 있음

사용 방법

  1. npm i prisma
  1. npx prisma init : 기본 설정 파일 생성(schema.prisma 파일을 생성 후 스키마 추가, .env 파일에 데이터베이스 연결 URL을 추가)
      • 밑에 코드들이 자동으로 생성&추가 됨
      // 데이터베이스 연결 URL을 설정 DATABASE_URL="file:./dev.db" //SQLite
      .env (.gitignore에 추가되어 있어야 함)
      datasource db { provider = "sqlite" // 사용할 데이터베이스 (sqlite, postgresql 등) url = env("DATABASE_URL") // DB 위치 } generator client { provider = "prisma-client-js" }
      prisma/schema.prisma
      fyi) SQLite?
      로컬 db. 서버 호스팅 안해도 됨
  1. Prisma 스키마 정의
    1. model User { id Int @id @default(autoincrement()) name String? email String @unique posts Post[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt }
      prisma/schema.prisma
      • createdAt, updatedAt는 사용되지 않더라도 기본으로 넣어주는 것이 좋음
  1. npx prisma migrate dev --name 저장이름 : 데이터베이스 마이그레이션
    1. ⇒ 스키마를 업데이트 할 때마다 이 명령어를 실행해야 함
      이후 생성되는 db관련 파일을 .gitignore파일에 추가해줘야 함
      *.db *.db-journal
      .gitignore
      • npx prisma generate 도 같이 실행 됨 : Prisma Client 생성
  1. Prisma Client 사용
    1. step 1) lib안에 ts파일 생성(여기선 lib/prisma.ts)
      step 2) Prisma Client 인스턴스 초기화
      // lib/prisma.ts import { PrismaClient } from '@prisma/client'; const prisma = new PrismaClient(); export default prisma;
  1. CRUD하기
    1. https://www.prisma.io/docs/orm/prisma-client/queries/crud 참고
      const users = await prisma.user.findMany();
      notion image
  • npx prisma studio : prisma Studio 실행
 

필드 속성

prismaprismaPrisma Schema API
Prisma Schema API

Prisma Schema API

API reference documentation for the Prisma Schema Language (PSL).

prismaprisma
: 속성 모음
  1. @id
      • 해당 필드를 Primary Key로 지정
      • Primary Key는 반드시 하나의 모델에 있어야 하며, Null 값을 허용 x
  1. @default
      • 필드의 기본값을 설정
      • 정적 값, 함수 등으로 값 설정 가능
      • 지원되는 함수: • autoincrement(): 자동 증가 값 (숫자 필드). • cuid(), uuid(): 고유 식별자 생성. • now(): 현재 시간.
      id Int @id @default(autoincrement()) createdAt DateTime @default(now()) status String @default("active")
  1. @unique
      • 해당 필드 값이 고유해야 함을 지정
  1. @map
      • Prisma 모델의 필드를 데이터베이스의 다른 열 이름에 매핑
        • firstName String @map("first_name")
  1. @relation
      • 모델 간 관계를 정의
      • 외래 키 및 참조 키를 명시적으로 지정
      author User @relation(fields: [authorId], references: [id]) authorId Int
  1. @@id
      • 복합 id, 두개의 값의 조합이 id가 된다
      model User { id Int @id @default(autoincrement()) name String post Post[] likes Like[] } model Post { id Int @id @default(autoincrement()) content String User User? @relation(fields: [userId], references: [id]) userId Int? likes Like[] } model Like { postId Int userId Int User User @relation(fields: [userId], references: [id]) Post Post @relation(fields: [postId], references: [id]) @@id([postId, userId]) }
 

쿼리 옵션

  1. where : 특정 조건을 만족하는 데이터 필터링
      • 조건 연산자: equals, contains, startsWith, endsWith, gt(greater than), lt(less than) 등.
      • 논리 연산자: AND, OR, NOT.
      // 특정 이메일을 가진 사용자 조회 const user = await prisma.user.findMany({ where: { email: "example@prisma.io", }, }); // 여러 조건을 결합하여 필터링 const users = await prisma.user.findMany({ where: { AND: [ { isActive: true }, { email: { contains: "@prisma.io" } }, ], }, });
  1. select : 필드 선택
      • 반환되는 데이터에서 특정 필드만 선택하여 가져옴
      // 사용자 이름과 이메일만 가져오기 const user = await prisma.user.findUnique({ where: { id: 1 }, select: { name: true, email: true, }, });
  1. include : 관계 데이터 포함(중첩)
    1. // 사용자와 해당 사용자의 게시물(Post)을 함께 가져오기 const userWithPosts = await prisma.user.findUnique({ where: { id: 1 }, include: { posts: true, }, });
  1. orderBy : 정렬
    1. // 사용자 데이터를 생성일 기준으로 내림차순 정렬 const users = await prisma.user.findMany({ orderBy: { createdAt: "desc", }, });
  1. take, skip : 페이징
      • take: 가져올 데이터의 최대 개수를 제한합니다.
      • skip: 지정된 개수만큼 데이터를 건너뜁니다.
      // 첫 번째 페이지의 첫 10명의 사용자 가져오기 const users = await prisma.user.findMany({ take: 10, skip: 0, }); // 두 번째 페이지의 다음 10명의 사용자 가져오기 const nextUsers = await prisma.user.findMany({ take: 10, skip: 10, });
  1. distinct : 중복 제거 • 특정 필드를 기준으로 중복 제거도 가능
    1. // 고유한 이메일을 가진 사용자 목록 가져오기 const uniqueEmails = await prisma.user.findMany({ distinct: ["email"], });
       

_count변수:
  • 최상위 레벨(include or select) 내부에서 사용할 수 있음
const posts = await prisma.post.findMany({ select: { id: true, title: true, description: true, views: true, created_at: true, _count: { select: { comments: true, likes: true, }, }, }, });
 

연산 in update
notion image
const updatePosts = await prisma.post.updateMany({ data: { views: { increment: 1, //views를 기존에서 +1 }, likes: { set: 0, //like를 0으로 set }, }, });

 

relation

B모델이 A모델을 참조하는걸 나타내려면?
ex)
model User { SMSToken SMSToken[] } model SMSToken { ... user User @relatioin(fields:[userId], references: [id]) //실제 db에는 추가ㄴㄴ userId Int //실제 db에는 이 id필드만 추가됨 }
@relatioin 코드 자동완성하는 법
  1. Prisma VScode extension 설치
  1. cmd + p
  1. JSON settings 파일을 열기
  1. 아래 코드 추가
    1. "[prisma]": { "editor.defaultFormatter": "Prisma.prisma" }
 
 
client 예시코드
const token = await prisma.sMSToken.create({ data: { token: "123123", user: { connect {//id 3인 사용자와 연결 (create는 사용자 생성) id: 3 } } } })
토큰 생성

onDelete

https://www.prisma.io/docs/orm/prisma-schema/data-model/relations/referential-actions
  • relation에서 어떤 모델이 다른 모델에 의해 참조되고 있다면, 그 모델은 삭제하지 못한다.
  • 삭제하려면? ⇒ 참조하는 모델도 같이 같이 삭제하는 방법!
    • onDelete: Cascade!
    • user User @relatioin(fields:[userId], references: [id]), onDelete: Cascade
  • onDelete: SetNull ⇒ 참조했던 모델이 삭제되면 필드 값이 null이 됨
    • 참조 필드를 optional로 둬야 함
      • user User? @relatioin(fields:[userId], references: [id], onDelete: SetNull) userId Int?
  • Restrict(기본값): 참조 레코드가 있는 경우 삭제를 방지
  • NoAction: Restrict과 유사하지만 사용 중인 데이터베이스에 따라 다릅
  • SetDefault: 참조 필드가 기본값으로 설정
 
 

  • VScode Extension 설치 권장
    • Prisma ⇒ 문법강조, 포매팅, 자동 완성 등
    • SQLite Viewer ⇒ .db 파일(스키마) 시각화
 

fyi
page에서 import 파일 >> 해당 페이지에 접속하면 해당 파일을 실행