JavaScript

Prisma

Node.js์šฉ์œผ๋กœ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” TypeScript ORM

  • #typescript
  • #prisma
  • #orm
  • #sql

Prisma๋Š” Node.js ๋ฐ Typescript์šฉ ORM ๋ ˆ์ด์–ด์ž…๋‹ˆ๋‹ค. Prisma๋Š” ์ฃผ๋กœ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์‚ฌ์šฉ๋˜์ง€๋งŒ MongoDb์™€ ๊ฐ™์€ no-SQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋Š” ์ถ”๊ฐ€ ๊ตฌ์„ฑ์„ ํ†ตํ•ด ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ถ€์ธ ์„ฑ๋ช…

ํ•œ๊ตญ์–ด ์‹ค๋ ฅ์ด ๋ถ€์ ํ•˜์—ฌ ์ด ๊ธ€์ด ๊ตฌ๊ธ€ ๋ฒˆ์—ญ๊ธฐ๋ฅผ ์ฃผ๋กœ ํ™œ์šฉํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ถ€์ •ํ™•ํ•œ ๋ฌธ๋ฒ•๊ณผ ์–ดํœ˜๊ฐ€ ์žˆ์„์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์  ์–‘ํ•ด ๋ถ€ํƒ๋“œ๋ฆฌ๋ฉฐ, ์ถ”ํ›„์— ๋‹ค์‹œ ๊ฒ€ํ† ํ•˜์—ฌ ์ˆ˜์ •ํ•˜๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

Prisma์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ 3๊ฐ€์ง€ ๊ตฌ์„ฑ ์š”์†Œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Prisma Client: Node.js ๋ฐ TypeScript์šฉ์œผ๋กœ ์ƒ์„ฑ๋œ ์œ ํ˜• ์•ˆ์ „ ์ฟผ๋ฆฌ ๋นŒ๋”์ž…๋‹ˆ๋‹ค.
  • Prisma Migrate: ์ง€์›๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ์‹œ์Šคํ…œ์ž…๋‹ˆ๋‹ค.
  • Prisma Studio: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด๋ถ€์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ณ  ํŽธ์ง‘ํ•˜๋Š” GUI ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

ํ…์ŠคํŠธ ์—๋””ํ„ฐ

์šฐ์„ , ๋Œ€๋ถ€๋ถ„์˜ ์ฝ”๋”ฉ ์ž‘์—…์— ์ ๊ทน ๊ถŒ์žฅ๋˜๋Š” ํ…์ŠคํŠธ ํŽธ์ง‘๊ธฐ๋Š” ๋ฌผ๋ก  Visual Studio Code์ž…๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” ๊ตฌ๋ฌธ ๊ฐ•์กฐ, ์ž๋™ ์„œ์‹ ์ง€์ • ๋“ฑ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋Š” Prisma ํ™•์žฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฐœ๋ฐœ์„ ๋น ๋ฅด๊ณ  ์ฆ๊ฒ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ์œ ์šฉํ•œ ์ฝ”๋“œ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜์—ฌ ๊ฐœ๋ฐœ์— ํž˜์„ ์‹ค์–ด์ค๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ์ดˆ๊ธฐํ™”

์‹œ์ž‘ํ•˜๋ ค๋ฉด ๋นˆ Node.js ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

npm init -y

๋‹ค์Œ์œผ๋กœ Prisma, TypeScript ๋ฐ ๊ธฐํƒ€ ๋ณด์™„ ์ข…์†์„ฑ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

npm install -D prisma typescript ts-node @types/node nodemon

์ข…์†์„ฑ์ด ์„ค์น˜๋˜๋ฉด ์ด์ œ ์•„๋ž˜ ๋ช…๋ น์„ ์‹คํ–‰ํ•˜์—ฌ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ Prisma ์ดˆ๊ธฐํ™”๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

npx prisma init

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‹คํ–‰ ์ถœ๋ ฅ๊ณผ ํ•จ๊ป˜ prisma ํด๋” ๋‚ด์— ์ถ”๊ฐ€๋œ schema.prisma๋ผ๋Š” ํŒŒ์ผ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

โœ” Your Prisma schema was created at prisma/schema.prisma
  You can now open it in your favorite editor.

Next steps:
1. Set the DATABASE_URL in the .env file to point to your existing database. If your database has no tables yet, read https://pris.ly/d/getting-started
2. Set the provider of the datasource block in schema.prisma to match your database: postgresql, mysql, sqlite, sqlserver, mongodb or cockroachdb.
3. Run prisma db pull to turn your database schema into a Prisma schema.
4. Run prisma generate to generate the Prisma Client. You can then start querying your database.

More information in our documentation:
https://pris.ly/d/getting-started

์ด์ œ๋Š” Prisma๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ดˆ๊ธฐํ™”๋˜์—ˆ์œผ๋ฉฐ ์ง„ํ–‰ํ•  ์ค€๋น„๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.

Prisma ์Šคํ‚ค๋งˆ

prisma ํด๋” ์•ˆ์—์˜ schema.prisma ํŒŒ์ผ์€ ๋‚ด๋ถ€์˜ ๋ชจ์Šต์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

schema.prisma
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema

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

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

์ด ์Šคํ‚ค๋งˆ ํŒŒ์ผ ๋‚ด์—์„œ ์„ธ๊ฐ€์ง€ ํ•ญ๋ชฉ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฐ์ดํ„ฐ ์†Œ์Šค: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค(ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด).
  • ์ƒ์„ฑ๊ธฐ: ์ƒ์„ฑํ•˜๋ ค๋Š” ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐ์ดํ„ฐ ๋ชจ๋ธ: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์‚ฌ์šฉ๋˜๋Š” ๋ชจ๋“  ๋ชจ๋ธ ๋ฐ ๊ด€๊ณ„

์ƒ์„ฑ๊ธฐ

generator client ๋‚ด๋ถ€์˜ ์ฝ˜ํ…์ธ ๋Š” ์‚ฌ์šฉ์ž ์ง€์ • ์Šคํ‚ค๋งˆ๋ฅผ ์ฝ๊ณ  ์ด๋ฅผ Visual Studio Code์˜ intellisense์—์„œ ํžŒํŠธ๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋Š” ์•ˆ์ „ํ•œ ํ˜•์‹์˜ ๋ณ€์ˆ˜๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์šฐ๋ฆฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋‚ด์—์„œ ์‚ฌ์šฉ๋  ํด๋ผ์ด์–ธํŠธ์ด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ๊ณต๊ธ‰์ž๋Š” prisma-client-js์ด๋ฉฐ ์ด ๊ธ€์„ ์“ฐ๋Š” ์‹œ์ ์—๋Š” ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋‹ค๋ฅธ ์œ ํ˜•์˜ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. ์ƒ์„ฑ๊ธฐ์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.

๋ฐ์ดํ„ฐ ์†Œ์Šค

datasource db๋Š” Prisma์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ ค๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์™€ ์—ฐ๊ฒฐ์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ดˆ๊ธฐํ™” ์ค‘์— ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์œผ๋ฉด PostgreSQL์ด ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋ฉ๋‹ˆ๋‹ค. env ํ•จ์ˆ˜๋Š” .env ํŒŒ์ผ์—์„œ DATABASE_URL์ด๋ผ๋Š” ๋น„๋ฐ€ ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. DATABASE_URL์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด์ž…๋‹ˆ๋‹ค.

PostgreSQL ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด์˜ ์ผ๋ฐ˜์ ์ธ ํ˜•์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

postgresql://USER:PASSWORD@HOST:PORT/DATABASE?schema=SCHEMA

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๋Œ€ํ•œ ์—ฐ๊ฒฐ ๋ฌธ์ž์—ด์— ๋Œ€ํ•œ .env ํŒŒ์ผ์˜ DATABASE_URL ๊ฐ’์„ ๋ฐ”๊พธ์‹ญ์‹œ์˜ค.

๋ชจํ…”

๋ชจ๋ธ์€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๋ ค๋Š” ์—”ํ„ฐํ‹ฐ๋ฅผ ์„ค๋ช…ํ•˜๋Š” ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์ž…๋‹ˆ๋‹ค. Prisma์—์„œ๋Š” model ํ‚ค์›Œ๋“œ๋กœ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

schema.prisma
model User {
    id Int @id @default(autoincrement())
    name String
}

Prisma๋Š” ๋ชจ๋“  ๋ชจ๋ธ์ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๊ฐ ํ•ญ๋ชฉ์„ ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ํ•˜๋Š” ๊ธฐ๋ณธ ํ‚ค ์—ญํ• ์„ ํ•˜๋Š” ์ผ์ข…์˜ ์‹๋ณ„์ž๋ฅผ ๊ฐ–๋„๋ก ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค.

๋ณด์‹œ๋‹ค์‹œํ”ผ Prisma ๋ชจ๋ธ ๋‚ด์˜ ํ•„๋“œ๋Š” ์ด๋ฆ„, ๋ฐ์ดํ„ฐ ์œ ํ˜• ๋ฐ ์†์„ฑ์˜ ์ˆœ์„œ๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค.

model User {
    <name> <datatype> @<attributes>
}

@id ์†์„ฑ์€ Prisma์—๊ฒŒ ํ•ด๋‹น ํ•„๋“œ๊ฐ€ ๊ธฐ๋ณธ ํ‚ค์ด๊ณ  @default()๊ฐ€ ๊ฐ์ฒด ์ƒ์„ฑ ์‹œ ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•จ์„ ์•Œ๋ ค์ค๋‹ˆ๋‹ค. autoincrement() ํ•จ์ˆ˜๋Š” ๊ฐ ํ›„์† ํ•ญ๋ชฉ์—์„œ id ๊ฐ’์„ 1์”ฉ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค. uuid()๋Š” ์ธ๋ฑ์Šค ํ•„๋“œ๋ฅผ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐ์—๋„ ์ผ๋ฐ˜์ ์ž…๋‹ˆ๋‹ค. ์†์„ฑ์— ๋Œ€ํ•ด์„œ๋Š” ๋‚˜์ค‘์— ๋” ์ž์„ธํžˆ ๋‹ค๋ฃจ๊ฒ ์Šต๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ํƒ€์ž…

Prisma์—๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์œ ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ ๋ฐ์ดํ„ฐ ์œ ํ˜•์€ ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ œ๊ณต๋˜๋Š” ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ์œ ํ˜•์„ ์ผ๋ฐ˜ํ™”ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๊ธฐ์„œ String์€ PostgreSQL์—์„œ๋Š” text ๋ฐ์ดํ„ฐ ์œ ํ˜•์— ๋งคํ•‘๋˜์ง€๋งŒ SQL Server์—์„œ๋Š” nvarchar(1000)์— ๋งคํ•‘๋ฉ๋‹ˆ๋‹ค. ์Šค์นผ๋ผ ์œ ํ˜•์— ๋Œ€ํ•ด ์ž์„ธํžˆ ์•Œ์•„๋ณด์„ธ์š”.

  • Int: ์ •์ˆ˜ํ˜•
  • String: ๋ชจ๋“  ์ข…๋ฅ˜์˜ ํ…์ŠคํŠธ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ์œ ํ˜•
  • ๋ถ€์šธ: ์ฐธ ๋˜๋Š” ๊ฑฐ์ง“
  • BigInt: ๋งค์šฐ ํฐ ์ •์ˆ˜
  • Float: ๋‹จ์ˆœ ๋ถ€๋™ ์†Œ์ˆ˜์ 
  • Decimal: ์ •ํ™•ํ•œ ๋ถ€๋™ ์†Œ์ˆ˜์ 
  • DateTime: ํƒ€์ž„์Šคํƒฌํ”„
  • Json: JSON ํ˜•์‹, ๋ชจ๋“  ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์—์„œ ์ง€์›๋˜์ง€๋Š” ์•Š์Œ
  • ๋ฐ”์ดํŠธ: ํฐ ๋ฉ์–ด๋ฆฌ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ ์›์‹œ ๋ฐ”์ดํŠธ ํ˜•์‹์˜ ๋ฐ์ดํ„ฐ
  • Unsupported(""): ์ง€์›ํ•˜์ง€ ์•Š๋Š” ํƒ€์ž…, ๋‹ค๋ฅธ db์—์„œ prisma๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ์‚ฌ์šฉ๋จ

ํƒ€์ž… ์ˆ˜์ •์ž

์œ ํ˜• ์ˆ˜์ •์ž๋Š” ํ•„๋“œ์˜ ๋™์ž‘์„ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Prisma์—๋Š” ๋‹จ 2๊ฐœ์˜ ์ˆ˜์ •์ž๊ฐ€ ์žˆ์œผ๋ฉฐ ์ดํ•ดํ•˜๊ธฐ๊ฐ€ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

  • nullable ์ˆ˜์ •์ž ?: ํ•„๋“œ๋ฅผ nullable๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฐฐ์—ด ์ˆ˜์ •์ž []: ํ•„๋“œ๊ฐ€ ์—ฌ๋Ÿฌ ๋ฐœ์ƒ์„ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

๊ด€๊ณ„

๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์—”ํ„ฐํ‹ฐ๊ฐ€ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋Š” ๊ด€๊ณ„์—๋Š” ์ผ๋Œ€์ผ, ์ผ๋Œ€๋‹ค, ๋‹ค๋Œ€์ผ, ๋‹ค๋Œ€๋‹ค์˜ 4๊ฐ€์ง€ ์œ ํ˜•์ด ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ผ๋Œ€๋‹ค: User๊ฐ€ ์—ฌ๋Ÿฌ Post๋ฅผ ๊ฐ€์ง€๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์Šคํ‚ค๋งˆ๋ฅผ ์ •์˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
schema.prisma
model User {
    id Int
    name String
    posts Post[]
}

model Post {
    id Int
    title String
    author User @relation(fields: [authorId], references: [id])
    authorId Int
}
  • ์ด์ค‘ ์ผ๋Œ€๋‹ค: ์‚ฌ์šฉ์ž๋Š” ๊ฒŒ์‹œ๋ฌผ์— ๋Œ€ํ•œ ๋‹ค์ค‘ ์ฐธ์กฐ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—๋Š” writePosts์™€ favouritePosts๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ์ผ๋Œ€๋‹ค ๊ด€๊ณ„ ๋ช…ํ™•ํ™”
schema.prisma
model User {
    id Int
    name String
    writtenPosts Post[] @relation("WrittenPosts")
    favouritePosts Post[] @relation("FavoritePosts")
}

model Post {
    id Int
    title String
    author User @relation("WrittenPosts", fields: [authorId], references: [id])
    authorId Int
    favoritedBy User? @relation("FavoritePosts", fields: [favoritedById], references: [id])
    favoritedById Int?
}
  • ๋‹ค๋Œ€๋‹ค: ํ•˜๋‚˜์˜ '๊ฒŒ์‹œ๋ฌผ'์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ '์นดํ…Œ๊ณ ๋ฆฌ'๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๊ณ  ํ•˜๋‚˜์˜ '์นดํ…Œ๊ณ ๋ฆฌ'๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ '๊ฒŒ์‹œ๋ฌผ'์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
schema.prisma
model Post {
    id Int
    title String
    categories Category[]
}

model Category {
    id Int
    name String
    posts Post[]
}
  • ์ผ๋Œ€์ผ: ํ•œ ๋ช…์˜ ์‚ฌ์šฉ์ž๊ฐ€ ํ•˜๋‚˜์˜ UserPreference ์„ธํŠธ๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
schema.prisma
model User {
    id Int
    name String
    preference UserPreference?
}

model UserPreference {
    id Int
    emailUpdates Boolean
    user User @relation(fields: [userId], references:[id])
    userId Int @unique
}

์ผ๋Œ€์ผ ๊ด€๊ณ„์ด๊ธฐ ๋•Œ๋ฌธ์— userId ํ•„๋“œ๋ฅผ @unique๋กœ ํ‘œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ณ ์œ ํ•˜์ง€ ์•Š์œผ๋ฉด ์˜๋ฏธ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

์†์„ฑ

์†์„ฑ์€ ํ•„๋“œ ๋˜๋Š” ๋ชจ๋ธ ๋ธ”๋ก์˜ ๋™์ž‘์„ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ์€ ๋ณ„์นญ ๊ธฐํ˜ธ @ ๋˜๋Š” @@์œผ๋กœ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.

ํ•„๋“œ ์ˆ˜์ค€ ์†์„ฑ

  • @id: ํ•„๋“œ๊ฐ€ ์‹๋ณ„์ž์ž„์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • @default(): ํ•ด๋‹น ํ•„๋“œ์˜ ๊ธฐ๋ณธ๊ฐ’์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • @default(autoincrement()): ์ •์ˆ˜ ํ•„๋“œ๋ฅผ 1์”ฉ ์ฆ๋ถ„ ์—…๋ฐ์ดํŠธํ•ฉ๋‹ˆ๋‹ค.
  • @default(uuid()): ๊ณ ์œ ํ•˜๊ฒŒ ์‹๋ณ„ ๊ฐ€๋Šฅํ•œ ๋ฌธ์ž์—ด์„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • @default(now()): ์ƒ์„ฑ ์‹œ ํƒ€์ž„์Šคํƒฌํ”„๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” DateTime ํ•„๋“œ์™€ ์Œ์„ ์ด๋ฃน๋‹ˆ๋‹ค.
  • @relation(): ํ•ด๋‹น ํ•„๋“œ์™€ ๋‹ค๋ฅธ ๋ชจ๋ธ ๊ฐ„์˜ ๊ด€๊ณ„๋ฅผ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • @unique: ๋™์ผํ•œ ๊ฐ’์„ ๊ฐ€์ง„ ํ•ญ๋ชฉ์„ ์‹œ๋„ํ•˜๋„๋ก ํ•„๋“œ๋ฅผ ๊ณ ์œ ํ•˜๊ฒŒ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • @updatedAt: ์ˆ˜์ • ์‹œ ํ•„๋“œ๋ฅผ ์ตœ์‹  ํƒ€์ž„์Šคํƒฌํ”„๋กœ ์ž๋™ ์—…๋ฐ์ดํŠธํ•˜๋Š” DateTime ํ•„๋“œ์™€ ์Œ์„ ์ด๋ฃน๋‹ˆ๋‹ค.

๋ธ”๋ก ์ˆ˜์ค€ ์†์„ฑ

๋‹จ์ผ ํ•„๋“œ ๋Œ€์‹  ์ „์ฒด ๋ชจ๋ธ์— ์ ์šฉ๋˜๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค.

  • @@unique([]): ๋ณตํ•ฉ ํ•„๋“œ์— ๊ณ ์œ  ์ œ์•ฝ ์กฐ๊ฑด์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.
schema.prisma
model User {
    id Int
    name String
    age Int

    @@unique([name, age])
}
  • @@index([]): ์ง€์ •๋œ ํ•„๋“œ์— ๋Œ€ํ•œ ์ธ๋ฑ์Šค ํ•„๋“œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ •๋ ฌ ๋ฐ ์„ฑ๋Šฅ์— ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.
schema.prisma
model User {
    id Int
    name String
    age Int

    @@unique([name, age])
    @@index([email])
}
  • @@id([]): ์ง€์ •๋œ ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณตํ•ฉ ID๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
schema.prisma
model User {
    // no more id field
    name String
    age Int

    @@id([name, age])
}
  • @@map([]): ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ์‹ค์ œ ์ด๋ฆ„์— ๋Œ€ํ•œ ํ˜„์žฌ ๋ชจ๋ธ์˜ ๋งคํ•‘์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
schema.prisma
model User {
    id Int
    name String
    age Int

    @@map("my_users")
}

์—ด๊ฑฐํ˜•

์šฐ๋ฆฌ์—๊ฒŒ ์ต์ˆ™ํ•œ ์ผ๋ฐ˜์ ์ธ ์—ด๊ฑฐํ˜•์ž…๋‹ˆ๋‹ค. ๊ณ ์ •๋œ ๊ฐ’ ์ง‘ํ•ฉ ๋˜๋Š” ํ•„๋“œ๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€ํ˜•์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

schema.prisma
enum Role {
    SUPERUSER,
    BASIC,
    READER
}

๊ทธ ํ›„์—๋Š” ๋ชจ๋ธ ๋‚ด๋ถ€์—์„œ ๋ฐ์ดํ„ฐ ์œ ํ˜•์œผ๋กœ ์‰ฝ๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

schema.prisma
model User {
    id Int
    name String
    role Role @default(BASIC)
}

Prisma ํด๋ผ์ด์–ธํŠธ

Prisma ํด๋ผ์ด์–ธํŠธ๋Š” VSCode์—์„œ ์ž๋™ ์™„์„ฑ ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•˜๋Š” ์Šคํ‚ค๋งˆ์— ์ •์˜ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ์œ ํ˜•์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์Šคํ‚ค๋งˆ ํŒŒ์ผ์ด ์ˆ˜์ •๋  ๋•Œ๋งˆ๋‹ค ๋‹ค์‹œ ์ƒ์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์Šคํ‚ค๋งˆ๊ฐ€ ํ™•์ •๋˜๋ฉด ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ์„ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

npx prisma generate

์ด ๋ช…๋ น์€ schema.prisma ํŒŒ์ผ์„ ๋ณ€๊ฒฝํ•  ๋•Œ๋งˆ๋‹ค ์‹คํ–‰๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

package.json์— ๋‚˜ํƒ€๋‚˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

package.json
"dependencies": {
ย  ย  "@prisma/client": "^4.4.0"
}

Create

๋ฃจํŠธ์— ์ง์ ‘ index.ts ํŒŒ์ผ์„ ๋งŒ๋“ค๊ณ  ๋‹ค์Œ ๋‚ด์šฉ์œผ๋กœ ์ฑ„์›๋‹ˆ๋‹ค.

index.ts
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()

async function main() {
  await prisma.user.create({
    data: {
      // populating data fields
      age: 17,
      name: 'Elrond',
      email: 'elrond@wix.com',
    },
  })
}

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

์œ„์˜ ์ฝ”๋“œ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋‚ด๋ถ€์— User ๊ฐœ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋กœ๊ทธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๋ฉด PrismaClient์— ์ธ์ˆ˜๋ฅผ ์ œ๊ณตํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

new PrismaClient({
  log: ['query', 'error', 'info', 'warn'],
})

Nested Create

User ์Šคํ‚ค๋งˆ ๋‚ด์— ์‚ฌ์šฉ์ž ์ •์˜ ๋ชจ๋ธ User Preference๊ฐ€ ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

schema.prisma
model User {
    id Int
    name String
    preference UserPreference
}

ํด๋ผ์ด์–ธํŠธ์—์„œ UserPreference ๋ชจ๋ธ์„ ์‚ฌ์šฉํ•˜์—ฌ User ์—”ํ„ฐํ‹ฐ๋ฅผ ๋ชจ๋‘ ์ธ์Šคํ„ด์Šคํ™”ํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.create({
  data: {
    // ... other fields of data
    preference: {
      create: {
        // ... data for `UserPreference`
      },
    },
  },
})

create ํ•จ์ˆ˜๋Š” ์ƒ์„ฑ ์ค‘์ธ ๊ฐœ์ฒด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์„ฑ๋œ ์ค‘์ฒฉ ํ•ญ๋ชฉ์€ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํฌํ•จํ•˜๋ ค๋ฉด include ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ํฌํ•จํ•  ๊ฐœ์ฒด๋ฅผ true๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

index.ts
await prisma.user.create({
  data: {
    // ... ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ
    preference: {
      create: {
        // ... `UserPreference`์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ
      },
    },
  },
  include: {
    preference: true,
  },
})

๋ฐ์ดํ„ฐ์˜ ์ผ๋ถ€๋งŒ ๊ฐ€์ ธ์˜ค๋ ค๋ฉด select ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  true๋กœ ์›ํ•˜๋Š” ํ•„๋“œ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.create({
  data: {
    // ... ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ
    preference: {
      create: {
        // ... `UserPreference`์— ๋Œ€ํ•œ ๋ฐ์ดํ„ฐ
      },
    },
  },
  select: {
    name: true,
  },
})

Select๋Š” ์ค‘์ฒฉ๋œ ๊ฐœ์ฒด์—์„œ๋„ ์ž˜ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ค‘์ฒฉ๋œ ๊ฐœ์ฒด๋ฅผ ์„ ํƒํ•˜๊ณ  GraphQL์ฒ˜๋Ÿผ ๋ฐ˜ํ™˜ํ•˜๋ ค๋Š” ํ•„๋“œ๋งŒ ๋Œ€์ƒ์œผ๋กœ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.create({
  data: {
    // ... other fields of data
    preference: {
      create: {
        // ... data for `UserPreference`
      },
    },
  },
  select: {
    name: true,
    preference: {
      select: {
        // field: true
      },
    },
  },
})

์ฐธ๊ณ : select์™€ include๋Š” ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๋‹จ์ง€ ๋‘˜ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค.

Create Many

ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋Œ€์‹  ํ•œ ๋ฒˆ์— ์—ฌ๋Ÿฌ ์ธ์Šคํ„ด์Šค๋ฅผ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

index.ts
await prisma.user.createMany([
  // ์‚ฌ์šฉ์ž ๋ฐฐ์—ด
])

ํŒ: createMany ๋‚ด์—์„œ๋Š” select๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

Find Unique

unique๋กœ ํ‘œ์‹œ๋œ ํ•„๋“œ๋ฅผ ํ†ตํ•ด ๊ฐœ์ฒด์˜ ์ธ์Šคํ„ด์Šค๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋‹ค์Œ ๋ชจ๋ธ์ด ์žˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๋ฉด findUnique๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ email ๋˜๋Š” ssn ํ•„๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ์ฒด๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

schema.prisma
model User {
    id Int
    name String
    email String @unique
    ssn String @unique
}
index.ts
const user = await prisma.user.findUnique({
  where: {
    email: 'abc@email.com',
  },
  // select? include? ๋Š” ์—ฌ๊ธฐ์— ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค
})

์—ฌ๋Ÿฌ ํ•„๋“œ์— ๊ฑธ์ณ ๋ธ”๋ก ์ˆ˜์ค€ ๊ณ ์œ  ์ œ์•ฝ ์กฐ๊ฑด์ด ์ง€์ •๋˜๋ฉด Prisma๋Š” ํ•„๋“œ ์ด๋ฆ„์„ ๋ณ€์ˆ˜๋กœ ๊ตฌ๋ถ„ํ•˜๋Š” ๋ฐ‘์ค„๋กœ ์ฐธ์กฐ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด์„œ

schema.prisma
model User {
    id Int
    name String
    age Int

    @@unique([name, age])
}

์ฟผ๋ฆฌ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ณ€์ˆ˜๋กœ name_age๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

index.ts
await prisma.user.findUnique({
  where: {
    name_age: {
      name: 'Ken',
      age: 27,
    },
  },
})

Find First

findUnique์˜ ๋ฌธ์ œ๋Š” name์ด๋‚˜ age๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์ฟผ๋ฆฌํ•  ์ˆ˜ ์—†๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•„๋“œ ์ค‘ ํ•˜๋‚˜๋งŒ ์ผ์น˜ํ•˜๋Š” ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ ๋Œ€์‹  findFirst๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.findFirst({
  where: {
    name: 'Hailey',
  },
})

Find Many

์ด๋ฆ„์ด ์ œ์•ˆํ•œ ๋Œ€๋กœ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์ฐพ๊ณ , ๊ฒ€์ƒ‰ ๊ธฐ์ค€์ด ๋ฐฐ์—ด๋กœ ์ถฉ์กฑ๋˜๋ฉด ์—ฌ๋Ÿฌ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

index.ts
await prisma.user.findMany({
  where: {
    age: 12,
  },
})

distinct ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ œ๊ณต๋œ ํ•„๋“œ์—์„œ ๊ณ ์œ ํ•˜๊ฒŒ ํ•„ํ„ฐ๋งํ•œ ํ›„ ์ฒซ ๋ฒˆ์งธ ๋ ˆ์ฝ”๋“œ๊ฐ€ ๋ฐ˜ํ™˜๋ฉ๋‹ˆ๋‹ค.

index.ts
await prisma.user.findMany({
  where: {
    name: 'Jack',
  },
  distinct: ['name', 'age'],
})

ํŽ˜์ด์ง€ ๋งค๊น€์„ ์œ„ํ•ด ๊ฒ€์ƒ‰ ์ฟผ๋ฆฌ ๋‚ด์—์„œ 'take' ๊ฐœ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. skip ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์ œ๊ณตํ•˜๋ฉด take๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— ๋จผ์ € ์ง€์ •๋œ ๋ ˆ์ฝ”๋“œ ์ˆ˜๋ฅผ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค.

index.ts
await prisma.user.findMany({
  where: {
    name: 'Jack',
  },
  take: 2,
  skip: 1,
})

์ •๋ ฌํ•˜๋ ค๋Š” ํ•„๋“œ๋ณ„๋กœ ๊ฒ€์ƒ‰ ๊ฒฐ๊ณผ๋ฅผ ์ •๋ ฌํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.findMany({
  where: {
    name: 'Jack',
  },
  orderBy: {
    age: 'asc',
  },
})

๊ณ ๊ธ‰ ํ•„ํ„ฐ๋ง

where ์ ˆ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋งŽ์€ ์ผ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

{
  "name": { "equals": "" },
  "name": { "not": "" },
  "name": { "in": ["Nick", "Josh"] },
  "name": { "notIn": ["Nick", "Josh"] },
  "age": { "lt": 20 },
  "age": { "gt": 20 },
  "age": { "gte": 20 },
  "age": { "lte": 20 },
  "email": { "contains": "@test.com" },
  "email": { "endsWith": "@gmail.com" },
  "email": { "startsWith": "hi" }
}

์—ฌ๋Ÿฌ ์ฟผ๋ฆฌ ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์—ฐ๊ฒฐํ•˜๋ ค๋ฉด 'AND', 'OR' ๋ฐ 'NOT'์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ชจ๋“  ์ฟผ๋ฆฌ๋ฅผ ํ•จ๊ป˜ ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.findMany({
  where: {
    AND: [{ name: { equals: 'Sam' } }, { age: { gte: 20 } }],
  },
})

๊ด€๊ณ„ ํ•„ํ„ฐ๋ง

ํ•˜์œ„ ๊ฐœ์ฒด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ์œ„ ๊ฐœ์ฒด๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. every๋Š” none๊ณผ some์œผ๋กœ ๋Œ€์ฒด๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.findMany({
  where: {
    // nested objects
    writtenPosts: {
      every: {
        title: 'test',
      },
    },
  },
})

๋‹ค์Œ์„ ํ†ตํ•ด ์ž‘์„ฑ์ž๊ฐ€ 20์„ธ์ธ ๋ชจ๋“  ๊ฒŒ์‹œ๋ฌผ์„ ์ฟผ๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.post.findMany({
  where: {
    author: {
      id: {
        age: 20,
      },
    },
  },
})

์—…๋ฐ์ดํŠธ

๋ฐ์ดํ„ฐ๋ฅผ ์ฟผ๋ฆฌํ•˜๊ณ  ์ด๋ฅผ ์—…๋ฐ์ดํŠธ๋œ ๋ฒ„์ „์œผ๋กœ ๋ฐ”๊ฟ‰๋‹ˆ๋‹ค. ๋ฐœ๊ฒฌ๋œ ๋ชจ๋“  ๋ ˆ์ฝ”๋“œ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๋˜ ๋‹ค๋ฅธ ๋ฒ„์ „์€ updateMany()์ž…๋‹ˆ๋‹ค.

index.ts
await prisma.user.update({
  where: {
    email: 'Test@test.com',
  },
  data: {
    email: 'Deck@test.com',
  },
})

Prisma์—๋Š” ์ •์ˆ˜ ๊ฐ’ ์—…๋ฐ์ดํŠธ์™€ ๊ด€๋ จํ•˜์—ฌ ๋ช‡ ๊ฐ€์ง€ ํฅ๋ฏธ๋กœ์šด ๊ธฐ๋Šฅ์ด ์žˆ์Šต๋‹ˆ๋‹ค. increment, decrement, multiply, divide์™€ ๊ฐ™์€ ์ˆ˜ํ•™ ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐ’์„ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.update({
  where: {
    email: 'Test@test.com',
  },
  data: {
    age: {
      increment: 1,
    },
  },
})

ํŒ: update*๋Š” ๊ณ ์œ  ํ•„๋“œ์— ๋Œ€ํ•ด ์ฟผ๋ฆฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Connect ๋ฉ”์†Œ๋“œ

Connect ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๊ธฐ์กด ๊ฐ์ฒด๋ฅผ ์ƒ์œ„ ๊ฐ์ฒด์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.update({
  where: {
    id: 123,
  },
  data: {
    userPreference: {
      connect: {
        // assuming already have a userPreference obj with the id
        id: 'abc123',
      },
    },
  },
})

disconnect๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ•ด๋‹น ๊ฐ์ฒด์— ๋Œ€ํ•œ ๊ธฐ์กด ์ฐธ์กฐ๋„ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

index.ts
await prisma.user.update({
  where: {
    id: 123,
  },
  data: {
    userPreference: {
      disconnect: true,
    },
  },
})

์‚ญ์ œ

delete ๋ฐ deleteMany๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค.

index.ts
await prisma.user.delete({
  where: {
    id: 123,
  },
})

์œ„ํ—˜: deleteMany ํ•จ์ˆ˜์— ์•„๋ฌด๊ฒƒ๋„ ์ „๋‹ฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ „์ฒด ํ…Œ์ด๋ธ”์ด ์ œ๊ฑฐ๋ฉ๋‹ˆ๋‹ค.