mysql 사용 기준으로 작성되어 몇몇 기능 및 지원에 대한 내용이 없을 수 있습니다.
Model 설명
데이터 모델은 애플리케이션의 주요 개념(예: 사용자, 게시글, 댓글 등)을 표현하는 객체가 되며 데이터베이스의 테이블에 매핑됩니다.
데이터 모델은 Prisma가 자동으로 생성하는 Prisma Client API의 기반이 되어 해당 모델에 대한 CRUD 쿼리 제공 및 자동으로 타입을 정의합니다.
모델 생성
Prisma 에서 데이터 모델을 생성하는 방법 2가지
- Introspection : 현재 DB 내용을 기준으로 데이터 모델 생성
- Model Definition : 데이터 모델을 수동으로 작성하고 DB 에 업데이트
1. Introspection
Prisma CLI 를 사용하여 데이터베이스를 내부적으로 조사하여 Prisma 스키마에서 데이터 모델을 생성할 수 있습니다.
Prisma ORM 을 기존 프로젝트에 추가할 때 데이터 모델의 초기 버전을 생성하는 데 주로 사용되며, Prisma Migrate를 사용하지 않고 일반 SQL이나 다른 마이그레이션 도구를 사용하여 스키마 마이그레이션을 수행하는 상황에 활용하는 경우가 일반적입니다.
# 데이터베이스 내용 schema 에 적용
prisma db pull
# 진행 과정
# 1. Prisma 스키마에서 데이터베이스 연결
# 2. 데이터베이스 스키마 읽기(Introspect)
# 3. 데이터베이스 스키마를 Prisma 스키마로 변환 후 Prisma 스키마 파일 업데이트
# 업데이트 된 Prisma 스키마 파일 기준으로 Prisma Client 업데이트
prisma generate
2. Model Definition
model [model name] {
// Fields Definition
}
// Model exmaple
model Profile {
id Int @id @default(autoincrement())
bio String
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
데이터 베이스와 매핑
// 모델 및 컬럼 매핑
model Comment {
firstName String @map("first_name") // 데이터베이스 컬럼 이름은 first_name
@@map("comments") // 데이터베이스 테이블 이름은 "comments"
}
enum(열거형) 매핑 사용 예
enum Role {
ADMIN
USER
GUEST
@@map("user_roles") // 데이터베이스에서는 'user_roles'라는 이름의 enum(열거형)을 사용
}
model User {
id Int @id @default(autoincrement())
name String
role Role @map("role_column") // 'role' 필드는 데이터베이스에서 'role_column'으로 저장
}
필드 정의
{
[필드 이름][?(optiona)] 필드 유형 (optional) 선택적 속성
...
}
model Comment {
id Int @id @default(autoincrement())
title String @db.VarChar(200) // native database type attributes
content? String
comments Comment[] // [Relation fields] A post can have many comments
}
속성 정의
- ID 필드 정의: @id
- Composite ID(복합 ID) : @@id([firstName, lastName]), @@id(name: "fullName", fields: [firstName, lastName])
- 기본값 정의: @default
- autoincrement: @default(autoincrement())
- 현재 시간을 기본값으로: @default(now())
- json type : @default("{ "hello": "world" }")
- 정적값 배열 : @default([5, 6, 8]), @default(["Hello", "Goodbye"])
- cuid, uuid : @default(cuid()) @default(uuid())
- 유니크 필드 정의: @unique
- compound unique constraints(복합 고유 제약 조건) : @@unique([authorId, title])
- 인덱스 정의: @index
- multi-column(다중 열 인덱스): @@index([title, content])
enum 정의
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
role Role @default(USER)
}
enum Role {
USER
ADMIN
}
모델 타입 정의
현재 model 구조를 반영해 Prisma Client 가 generate 과정 중 model type 을 정의하며, 정의된 type 은 데이터베이스 쿼리에서 type 의 안정성이 보장되며, 컴파일 시점에 검증되도록 보장
Relations
관계 필드는 Prisma ORM 수준에서 모델 간의 연결을 정의하며 데이터베이스에 존재하지 않습니다.
@relation 속성에서 참조하는 필드는 데이터베이스에 존재하며 관계된 테이블을 연결하는 외래 키입니다.
관계 필드
- relation field : 관계 필드는 스칼라 유형이 아닌 Prisma 모델의 필드입니다. ex) User.posts, Post.author
- annotated relation field : 관계 필드 중 @relation 을 사용하는 필드 즉 관계에서 외래 키를 저장하는 쪽의 필드를 의미 ex) Post.Author
- relation scalar field : @relation 의 인자 fields 로 지정된 필드 즉 실제 데이터베이스에 저장되는 외래 키 필드 ex) Post.authorId
// example
model User {
id Int @id @default(autoincrement())
email String @unique
role Role @default(USER)
posts Post[] // "relation field" (defined only at the Prisma ORM level)
}
model Post {
id Int @id @default(autoincrement())
title String
author User @relation(fields: [authorId], references: [id]) // "annotated relation fields" (uses the relation scalar field `authorId` below)
authorId Int // "relation scalar field" (used in the `@relation` attribute above)
}
@relation 속성 정의
- name: 관계의 이름을 정의하며, M-N 관계에서는 중간 테이블의 이름도 결정.
- fields: 현재 모델에서 외래 키로 사용되는 필드 목록. (annotated relation field 에서 필수)
- references: 관계된 다른 모델에서 참조하는 필드 목록. (annotated relation field 에서 필수)
- map: 데이터베이스에서 외래 키의 커스텀 이름을 정의.
- onUpdate: 참조된 항목이 업데이트될 때 수행할 동작을 정의. (*referential actions)
- onDelete: 참조된 항목이 삭제될 때 수행할 동작을 정의. (*referential actions)
※*referential actions: Cascade, Restrict, NoAction, SetNull, SetDefault
one-to-one (일대일 관계)
model User {
id Int @id @default(autoincrement())
profile Profile? // "relation field"
}
model Profile {
id Int @id @default(autoincrement())
user User @relation(fields: [userId], references: [id]) // "annotated relation field"
userId Int @unique // relation scalar field (used in the `@relation` attribute above)
}
다중 필드 관계
model User {
firstName String
lastName String
profile Profile?
@@id([firstName, lastName])
}
model Profile {
id Int @id @default(autoincrement())
user User @relation(fields: [userFirstName, userLastName], references: [firstName, lastName])
userFirstName String // relation scalar field (used in the `@relation` attribute above)
userLastName String // relation scalar field (used in the `@relation` attribute above)
@@unique([userFirstName, userLastName])
}
one-to-many relations (일대다 관계)
model User {
id Int @id @default(autoincrement())
posts Post[] // One-to-many relations field
}
model Post {
id Int @id @default(autoincrement())
author User @relation(fields: [authorId], references: [id])
authorId Int
}
many-to-many relations (다대다 관계)
- Explicit many-to-many relations: 명시적 다대다 관계
- Implicit many-to-many relations: 암시적 다대다 관계
1. Explicit many-to-many relations (명시적 다대다 관계)
다대다 관계의 관계 테이블을 Prisma 스키마 모델로 정의해 사용하는 방식으로 직접적으로 쿼리를 사용할 수 있고 추가적으로 데이터를 저장해야 하는 경우 유용합니다.
model Post {
id Int @id @default(autoincrement())
categories CategoriesOnPosts[] // 명시적(Explicit)관계 표시
}
model Category {
id Int @id @default(autoincrement())
posts CategoriesOnPosts[] // 명시적(Explicit)관계 표시
}
// 명시적(Explicit)으로 다대다 관계 테이블 정의
model CategoriesOnPosts {
post Post @relation(fields: [postId], references: [id])
postId Int // relation scalar field (used in the `@relation` attribute above)
category Category @relation(fields: [categoryId], references: [id])
categoryId Int // relation scalar field (used in the `@relation` attribute above)
assignedAt DateTime @default(now())
assignedBy String
@@id([postId, categoryId])
}
Implicit many-to-many relations (암시적 다대다 관계)
다대다 관계의 관계 테이블을 Prisma 가 관계 테이블을 간단하게 자동으로 생성해주는 방식으로 추가적인 데이터를 저장할 필요 없을 때 유용합니다.
model Post {
id Int @id @default(autoincrement())
title String
categories Category[] // 암시적(Implicit)관계 표시
}
model Category {
id Int @id @default(autoincrement())
name String
posts Post[] // 암시적(Implicit)관계 표시
}
Multi-file Prisma Schema
Prisma Schema의 generator 블록의 previewFeatures 필드에 prismaSchemaFolder 기능 플래그를 추가하여 사용
// prisma/schema.prisma
generator client {
provider = "prisma-client-js"
previewFeatures = ["prismaSchemaFolder"] // need this line to use Multi-file Prisma Schema
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
// 폴더 구조 예시
my-app/
├─ ...
├─ prisma/
│ ├─ schema/
│ │ ├─ post.prisma
│ │ ├─ schema.prisma
│ │ ├─ user.prisma
├─ ...
※디렉토리 구조 tip
- 도메인별로 파일을 정리
- datasource 와 generator 블록을 정의하는 "기본" 스키마 파일 정의 ex) main.prisma, schema.prisma, base.prisma
참고
'Prisma' 카테고리의 다른 글
[Prisma] 6. Pagination & Aggregation (0) | 2025.01.18 |
---|---|
[Prisma] 5. Nested Queries (0) | 2025.01.17 |
[Prisma] 4. query filtering & sorting (0) | 2025.01.17 |
[Prisma] 3. Prisma query 사용 (CRUD, query options) (0) | 2025.01.14 |
[Prisma] 1. Prisma 란 무엇인가? (0) | 2025.01.11 |