2024. 7. 23. 18:16ㆍORM
Prisma ORM: 기본 개념과 동작 원리
Prisma ORM이란?
Prisma ORM은 차세대 오픈소스 ORM입니다.
ORM은 "Object-Relational Mapping"의 약자로, 객체-관계 매핑을 의미합니다. ORM은 데이터베이스의 테이블과 프로그래밍 언어의 객체 사이의 매핑을 자동화하여, 데이터베이스와의 상호작용을 더 쉽고 효율적으로 만들어줍니다. 왜냐하면 개발자가 객체 지향 언어로 데이터베이스의 데이터를 더 쉽게 조작할 수 있게 해 주기 때문입니다. ORM을 사용하면 SQL 쿼리 없이 데이터를 데이터베이스에 저장하고 관리할 수 있습니다.
다음과 같은 구성 요소로 이루어져 있습니다.
Prisma Client: 자동 생성되고 타입 안전한 Node.js 및 TypeScript용 쿼리 빌더
Prisma Migrate: 마이그레이션 시스템
Prisma Studio: 데이터베이스의 데이터를 보고 편집할 수 있는 GUI로 이 부분은 오픈소스가 아닙니다.
Prisma Client는 모든 Node.js(지원되는 버전) 또는 TypeScript 백엔드 애플리케이션(서버리스 애플리케이션 및 마이크로서비스 포함)에서 사용할 수 있습니다. 여기에는 REST API, GraphQL API, gRPC API 또는 데이터베이스가 필요한 모든 것이 포함될 수 있습니다.
Prisma 스키마는 강력한 데이터 모델링 기능을 가지고 있습니다. 예를 들어, "Prisma-lelvel"의 관계 필드를 정의할 수 있어 Prisma 클라이언트 API에서 relations 작업을 더 쉽게 할 수 있습니다. 자세히 알아보겠습니다.
relations
관계는 프리즈마 스키마에서 두 모델 간의 연결입니다. 예를 들어, 한 사용자가 많은 블로그 글을 가질 수 있으므로 사용자와 게시물 사이에는 일대다 관계가 있습니다. 다음 프리즈마 스키마는 사용자 모델과 게시물 모델 간의 일대다 관계를 정의합니다.
model User {
id Int @id @default(autoincrement())
posts Post[]
}
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int // relation scalar field (used in the `@relation` attribute above)
}
두 개의 관계 필드: User의 posts와 Post의 author. 관계 필드는 Prisma ORM level에서 모델 간의 연결을 정의하며 데이터베이스에는 존재하지 않습니다. 이러한 필드는 Prisma Client를 생성하는 데 사용됩니다.
Post의 authorId는 @relation 속성에서 참조하는 스칼라 필드입니다. 이 필드는 데이터베이스에 존재하며 게시물과 사용자를 연결하는 외래 키입니다.
Prisma ORM은 어떻게 동작하는가?
Prisma ORM 툴킷을 사용하는 모든 프로젝트는 Prisma schema로 시작합니다. Prisma schema는 개발자가 직관적인 데이터 모델링 언어로 애플리케이션 모델을 정의할 수 있게 해 줍니다. 또한 데이터베이스 연결을 포함하고, generator를 정의합니다.
//schema.prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}
- Prisma schema는 datasoruce, generator, model 이 세 가지 요소로 구성됩니다.
- 데이터 모델은 데이터베이스에서 데이터를 어떻게 저장할지를 정의하는 구조입니다.
- Prisma schema에서는 모델이라는 개념을 사용해서 데이터베이스의 테이블(관계형 데이터베이스)이나 컬렉션(MongoDB)을 정의합니다.
- Prisma Client를 사용하면, model을 통해 생성된 테이블에서 데이터를 추가하거나 조회할 수 있습니다.
Prisma Client 사용하기
Prisma Client를 사용하려면 첫 번째 단계로 @prisma/client npm 패키지를 설치해야 합니다:
npm install @prisma/client
@prisma/client 패키지를 설치하면, prisma generate 명령이 자동으로 실행되어 Prisma 스키마를 읽고 Prisma Client 코드를 생성합니다. 기본적으로 생성된 코드는 node_modules/.prisma/client 폴더에 저장됩니다.
데이터 모델을 변경한 후에는, node_modules/.prisma/client 폴더의 코드가 업데이트되도록 Prisma Client를 수동으로 다시 생성해야 합니다:
npx prisma generate
Prisma Client 사용 예시
import { PrismaClient } from '@prisma/client'
const prisma = new PrismaClient()
//Retrieve all User records from the database
// Run inside `async` function
const allUsers = await prisma.user.findMany()
//Include the posts relation on each returned User object
// Run inside `async` function
const allUsers = await prisma.user.findMany({
include: { posts: true },
})
// Filter all Post records that contain "prisma"
// Run inside `async` function
const filteredPosts = await prisma.post.findMany({
where: {
OR: [
{ title: { contains: 'prisma' } },
{ content: { contains: 'prisma' } },
],
},
})
// Create a new User and a new Post record in the same query
// Run inside `async` function
const user = await prisma.user.create({
data: {
name: 'Alice',
email: 'alice@prisma.io',
posts: {
create: { title: 'Join us for Prisma Day 2020' },
},
},
})
// Update an existing Post record
// Run inside `async` function
const post = await prisma.post.update({
where: { id: 42 },
data: { published: true },
})
Prisma ORM Workflow
Data model을 Prisma schema로 가져오는 방법에는 두 가지가 있습니다. 어떤 접근 방식을 선택하느냐에 따라 기본 Prisma ORM 워크플로가 달라질 수 있습니다.
방법 01. Prisma Migrate 사용
Prisma ORM의 통합 데이터베이스 마이그레이션 도구인 Prisma Migrate를 사용할 때의 작업 흐름은 다음과 같습니다:
- 'schema.prisma' 파일을 수정해 데이터 모델을 업데이트 합니다.
prisma migrate dev
로 개발 환경의 데이터베이스에 변경사항을 적용합니다.- 애플리케이션 코드에서 Prisma Client를 사용하여 데이터베이스에 접근합니다.
prisma migrate dev
명령어 사용 시 다음과 같은 에러가 발생할 수 있습니다.
1. prisma migrate 이전에 데이터베이스를 사용 중이었을 경우
2. 데이터베이스의 데이터가 유지되어야 하는 경우
에러메시지에서도 알 수 있다시피, 위 경우에는 Baselining을 통해 데이터베이스 마이그레이션 기록을 초기화해줘야 합니다. 데이터베이스에 이미 존재하는 테이블과 필드가 있는 상황에서 Prisma Migrate가 이를 다시 생성하려 하면 오류가 발생할 수 있습니다. 베이스라이닝은 이러한 문제를 해결하는 방법입니다. 베이스라이닝을 통해 Prisma Migrate에게 특정 마이그레이션들이 이미 적용된 것으로 간주하도록 설정할 수 있습니다. 이를 통해 Prisma Migrate는 해당 마이그레이션들을 건너뛰고, 실제로 필요한 새로운 마이그레이션만을 적용하게 됩니다.참고: migrate-baseline
방법 02. SQL 마이그레이션과 introspection
- SQL 등을 활용해서 데이터베이스 스키마를 변경합니다.
- 데이터베이스 introspection: 현재 데이터베이스 스키마를 기반으로 Prisma 스키마를 업데이트합니다.
- Prisma Client API를 (재)구성하기(선택): 데이터베이스 스키마를 변경한 후, 필요에 따라 Prisma Client API의 설정을 조정할 수 있습니다.
- (재)생성된 Prisma Client 사용하기: Prisma Client를 재생성하여 최신 스키마를 반영하도록 하고, 애플리케이션 코드에서 Prisma Client를 사용하여 데이터베이스에 접근합니다.
이상으로 Prisma의 기본 개념과 동작 원리, 사용법에 대해 알아보았습니다.
참고
What is Prisma ORM? | Prisma Documentation