February 12, 2021
⚠️ 이번 장에서는 Prisma 환경세팅은 다루지 않기 때문에 Prisma를 설치하지 않으신 분은 여기를 참고하세요.
generator client {
provider = "prisma-client-js"
}
datasource mysql {
provider = "mysql"
url = env("API_MYSQL_URL")
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
title String
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
categories Category[] @relation(references: [id])
...
}
Prisma를 사용하기 위해서는 일단 model을 만들어야 합니다. 그래야 이를 바탕으로 DB schema, type도 생성하기 때문입니다. model을 생성하는데 알아야 하는 다양한 옵션이 있습니다. 이런 옵션들을 제대로 알아야 원하는 DB schema를 정확하게 구현할 수 있습니다.
이번장에서는 model을 생성하는데 알아야 하는 것이 어떤 것들이 있는지 알아보겠습니다 ❗️
📌 : 꼭 필요한 option을 의미
연결하려는 데이터베이스에 대한 설정을 다루는 부분입니다.
datasource db {
provider = "mysql"
url = "mysql://johndoe:mypassword@localhost:3306/mydb""
}
provider
📌
어떤 DB를 사용할지 명시
url
📌
DB server의 URL을 명시, DB마다 선언 방법이 다름 몇몇 방법으로 선언할 수 있음
연결에 대해 여러 옵션, SSL connetion 설정 가능(여기 참고)
env("DATABASE_URL")
가능prisma generate시 생성되는 자원을 결정합니다.
generator client {
provider = "prisma-client-js"
output ="./src/generated/client"
binaryTargets = ["linux-msl"]
previewFeatures = ["sample-preview-feature"]
}
provider
📌
사용할 generator을 지정, generator을 구현하는 파일을 지정, 내장 generator을 직접 지정할 수 있습니다. 하나 또는 여러개를 가질 수 있으며 현재는 prisma-client-js만 사용할 수 있습니다.
output
prisma generate시 생성되는 @prisma/client의 위치를 기술합니다. default 위치는 node_modules/@prisma/client 입니다.
binaryTargets
query engine의 바이너리 호환성을 보장하기 위해 Prisma Client가 실행될 OS를 지정합니다. “native” 로 지정할 경우 Prisma가 여기를 고려하여 현재 OS에 알맞은 binary target을 찾은 후 지정합니다. 또한 Custom binary를 사용할 수 있습니다.
output
현재 사용가능한 Preview features를 알아봅니다. 사용법은 prisma release 2.16.0을 보면 createMany api는 현재 preview 단계 이므로 createMany를 사용하기 위해서는 previewFeatures = [“createMany”]를 추가해주어야 합니다.
Prisma model을 정의합니다. model은 User, Post…등 @prisma/client에서 사용하는 model 그리고 DB table을 의미합니다. model명은 model의 모든 데이터(row)는 고유하게 식별할 수 있어야 하며 model을 정의할 때 아래의 attributes중 하나를 반드시 사용해야 합니다.
@unique
@@unique
@id
@@id
model 명은 [A-Za-z][a-za-z0-9_]* 모양의 정규식 형태를 가집니다. 또한 문자로 시작하며 PascalCase 로 표기됩니다(model attributes는 camelCase형태를 가집니다)
model을 정의할 때 사용할 수 있는 data type 단위로 실제 DB native data type으로 변환되며(String → varchar(191)) 아래의 scalar type을 지원합니다.
String
Boolean
Int
Float
DateTime
Json
Decimal
Bytes
BigInt
추가적으로 model이 relation을 가지는 경우 model field type을 가질 수 있습니다.
2.11.0+ 부터는 확장된 native type을 지원하며 자세한 내용은 여기를 참고하세요.
model field scalar type에는 2가지의 식별자를 추가할 수 있습니다.
[]
scalar type을 배열로 만드며 optional일 수 없습니다(Post[]? ❌). model type이 기본 scalar type은 해당 DB가 list를 지원해주어야만 사용 가능합니다. 현재 scalar list는 PostgreSQL만 지원합니다. MySQL와 SQLite 는 기본적으로 list를 지원하지 않습니다.
model간에 관계가 있을 때, 예를 들어 User와 Post의 관계가 1:N일 때 Post[]로 표현할 수 있으며 Post model에서는 userId를 정의해야 합니다.
?
scalar type을 optional하게 만듭니다. 배열로 만드는 경우 ?를 사용할 수 없으며 ? 식별자를 붙인 scalar type은 nullable 특징을 가집니다. 아무것도 붙이지 않으면 not null 특징을 가집니다.
filed 또는 model의 option을 추가하며 여기에는 2가지 방법이 있습니다.
일부 속성은 arguments를 필요로 하며 arguments를 사용하는 경우 항상 이름은 지정해야 하지만 대부분의 경우 arguments를 생략할 수 있습니다
@id
@id
autoincrement()
uuid()
cuid()
@@id
@@id(fields: [title, author])
@@id([title, author])
❗️ N:M관계를 관리하는 hashTagsPosts model의 경우 [hashTagId,postId]를 사용하여 각각의 row를 유일하게 구분할 수 있기 때문에 이런 경우 @@id를 사용합니다.
@default
id Int @id @default(value: autoincrement())
id Int @id @default(autoincrement())
4가지의 함수 사용가능
autoincrement()
cuid()
uuid()
now()
@unique
@unique
@@unique
@@unique(fields: [title, author])
@@unique([title, author])
@@unique(field: [title, author], name: "titleAuthor")
unique 명은 titleAuthor, UNIQUE KEY `titleAuthor` (`firstName`,`secondName`)
@@index
@@index(fields: [title, author])
@@index([title, author])
@@index(fields: [title, content], name: "main_index")
@@relation
@relation(name: "UserOnPost", fields:[authorId], references: [id])
@relation("UserOnPost", references: [id])
@relation(name: "UserOnPost")
@relation("UserOnPost")
name
은 relation을 구분, fields
는 외래키 filed, references
는 외래키가 참조하는 id
❗️ name이 서로 동기화가 되지 않으면 N쪽의 테이블에서 새로운 field 만듦
model User {
id Int @id @default(autoincrement())
posts Post[] @relation(name:"Test1")
}
model Post {
id Int @id @default(autoincrement())
author User @relation(name:"Test2",fields:[authorId],references: [id])
authorId Int
}
위와 같은 구조에서 생성된 테이블은 새로운 filed와 constraint가 생성된다. 아마 name으로 relation을 구분하는데 동기화가 되어있지 않으니 Prisma가 Post쪽의 model 정보를 사용하여 관계를 임의로 만든 것 같다.
CONSTRAINT `post_ibfk_2` FOREIGN KEY (`userId`) REFERENCES `User` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
@map
@map(name: "is_admin")
@map("users")
@@map
@@map(name: "users")
@@map("users")
@updatedAt
@updatedAt
autoincrement()
id Int @id @default(autoincrement())
cuid()
id Int @id @default(cuid())
uuid()
id Int @id @default(uuid())
now()
createAt DateTime @default(now())
dbgenerated()