Node.js · 2025-12-21

Prisma로 타입 안전한 DB 개발 시작하기

Prisma를 사용해 TypeScript 환경에서 타입 안전한 데이터 모델과 쿼리를 설계하고 마이그레이션과 클라이언트 사용 예제를 포함해 설명하는 개발 자료

작성일 : 2025-12-21 ㆍ 작성자 : 관리자
post
목차

소개

Prisma는 타입 안전성을 강조하는 ORM으로, TypeScript와 함께 사용하면 런타임 전 컴파일 단계에서 많은 오류를 발견할 수 있다. 이 글은 Prisma의 핵심 개념과 실무에서 바로 적용할 수 있는 예제를 통해 Prisma Node.js 사용법과 Prisma ORM 튜토리얼을 제공한다. 처음 접하는 개발자도 이해하기 쉽도록 단계별로 설명한다.

사전 준비

환경은 Node.js와 TypeScript가 설치된 상태를 전제로 한다. 데이터베이스는 PostgreSQL, MySQL, SQLite 등 Prisma에서 지원하는 어느 엔진을 사용해도 무방하다. 프로젝트 초기화와 Prisma 설치 과정은 다음과 같다.

프로젝트 초기화

npm init -y
npm install prisma --save-dev
npm install @prisma/client
npx prisma init

위 절차를 통해 Prisma 설정 파일인 schema.prisma와 .env가 생성된다. .env에 데이터베이스 연결 문자열을 설정하면 마이그레이션과 클라이언트 생성이 가능하다.

schema.prisma 구조 이해

schema.prisma는 모델과 데이터베이스 연결을 정의하는 핵심 파일이다. 모델 필드에 타입을 명시하면 Prisma가 타입 정보를 기반으로 클라이언트를 자동 생성한다. 기본적인 예는 다음과 같다.

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

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

model User {
  id        Int      @id @default(autoincrement())
  email     String   @unique
  name      String?
  posts     Post[]
  createdAt DateTime @default(now())
}

model Post {
  id        Int      @id @default(autoincrement())
  title     String
  content   String?
  author    User     @relation(fields: [authorId], references: [id])
  authorId  Int
  createdAt DateTime @default(now())
}

이 예제에서 User와 Post 간에 1:N 관계가 설정되어 있다. 모델 정의 후 마이그레이션을 생성하면 데이터베이스에 스키마가 반영된다.

마이그레이션과 클라이언트 생성

마이그레이션은 Prisma Migrate로 관리된다. 마이그레이션 생성과 적용은 다음 절차로 진행된다.

npx prisma migrate dev --name init
npx prisma generate

마이그레이션 적용 후 Prisma Client가 자동 생성된다. 생성된 클라이언트는 타입 정보를 포함하므로 코드 작성 시 높은 타입 안전성을 제공한다.

Node.js와의 통합 예제

간단한 CRUD 예제는 다음과 같다. TypeScript 환경에서 Prisma Client를 임포트하면 편리한 자동완성과 타입 검사가 가능하다.

import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()

async function main() {
  const user = await prisma.user.create({
    data: { email: 'alice@example.com', name: 'Alice' }
  })

  const post = await prisma.post.create({
    data: {
      title: 'Prisma 소개',
      content: 'Prisma로 타입 안전한 데이터베이스 작업',
      authorId: user.id
    }
  })

  const feed = await prisma.post.findMany({
    where: { published: false },
    include: { author: true }
  })

  console.log({ user, post, feed })
}

main().catch(e => console.error(e)).finally(async () => await prisma.$disconnect())

위 예제는 Node.js Prisma 예제로 활용될 수 있다. findMany나 create 같은 메서드에서 타입 안전성이 유지된다.

관계 쿼리와 선택적 필드

Prisma는 include와 select를 통해 필요한 필드만 가져오도록 지원한다. 이는 성능과 타입 정확성 모두에 유리하다.

const postsWithAuthor = await prisma.post.findMany({
  include: { author: { select: { id: true, name: true } } }
})

트랜잭션과 성능

복수 쿼리를 원자적으로 실행해야 할 때는 트랜잭션을 사용한다. Prisma는 $transaction API를 제공한다. 또한 필요 시 raw 쿼리 실행이 가능하다.

await prisma.$transaction(async (tx) => {
  const u = await tx.user.create({ data: { email: 'bob@example.com' } })
  await tx.post.create({ data: { title: '트랜잭션 테스트', authorId: u.id } })
})

테스트와 타입 검증

단위 테스트에서 Prisma Client는 테스트용 데이터베이스와 함께 사용된다. 타입 검증은 컴파일 타임부터 이루어지므로 테스트 작성 시 타입 관련 버그가 줄어든다. 테스트 전략은 다음과 같다.

  • 테스트 전용 데이터베이스 또는 SQLite 사용
  • 마이그레이션 적용 후 테스트 실행
  • 테스트마다 데이터 초기화

실무 적용 시 고려 사항

Prisma를 도입할 때는 다음 점을 고려하면 안정적인 운영에 도움이 된다.

  • 데이터베이스 스키마 변경은 마이그레이션으로 일관성 있게 관리
  • 복잡한 관계 쿼리는 인덱스와 쿼리 플랜을 검토
  • 대량 데이터 처리 시 배치 처리와 cursor 기반 페이징 고려
  • 비즈니스 로직과 데이터 접근 계층을 분리해 테스트 용이성 확보

마무리

Prisma는 TypeScript 환경에서 높은 수준의 타입 안전성을 제공한다. Prisma Node.js 사용법을 익히면 쿼리 작성과 모델 관리를 더 신뢰성 있게 수행할 수 있다. 이 글의 예제는 Prisma ORM 튜토리얼로서 Node.js Prisma 예제와 함께 실무 적용에 도움이 되는 출발점을 제공한다.

Prisma Node.js 사용법 Prisma ORM 튜토리얼 Node.js Prisma 예제 Prisma TypeScript ORM Prisma Migrate Prisma Client 데이터베이스 타입 안전성