๐Ÿ”ฅ Prisma์™€ ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰์œผ๋กœ ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ ์ถ”๊ฐ€ํ•˜๊ธฐ

Jisunminยท2025๋…„ 6์›” 23์ผ
post-thumbnail

๐Ÿค” Supabase ํ…Œ์ด๋ธ” ์ƒ์„ฑ ํ›„ ๋ฐ์ดํ„ฐ ๊ด€๋ฆฌ ๊ด€๋ จ ๊ณ ๋ฏผ๊ณผ Prisma ์‚ฌ์šฉ ์ด์œ 

Supabase์—์„œ ํ…Œ์ด๋ธ”์„ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ณ  ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ insertํ•˜๋Š” ๊ฒฝ์šฐ,
ํ„ฐ๋ฏธ๋„์—์„œ prisma db pull ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด Prisma ์Šคํ‚ค๋งˆ์™€ ์‹ค์ œ DB ์ƒํƒœ ๊ฐ„์— ์ฐจ์ด๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋กœ ์ธํ•ด Prisma๊ฐ€ ํžˆ์Šคํ† ๋ฆฌ ๋ถˆ์ผ์น˜๋ฅผ ๊ฐ์ง€ํ•˜๊ณ ,
์ข…์ข… โš ๏ธreset(์žฌ์„ค์ •)์„ ํ•˜๋ผ๋Š” ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€๊ฐ€ ๋‚˜์˜ค๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค

โ—๋ฌธ์ œ์ 

  • Supabase ์ฝ˜์†”๊ณผ Prisma ์Šคํ‚ค๋งˆ ๊ฐ„ ๋™๊ธฐํ™”๊ฐ€ ์–ด๋ ค์›€
  • ์ง์ ‘ Supabase์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ •ํ•˜๋ฉด Prisma ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ธฐ๋ก๊ณผ ์ถฉ๋Œ ๊ฐ€๋Šฅ์„ฑ ์žˆ์Œ
  • Prisma๋ฅผ ํ†ตํ•œ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๊ด€๋ฆฌ๊ฐ€ ๋ถˆ์™„์ „ํ•ด์งˆ ์œ„ํ—˜
  • reset ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๋˜์–ด ๋‹ค์‹œ ์„ธํŒ…ํ•ด์•ผ ํ•˜๋Š” ๋ฒˆ๊ฑฐ๋กœ์›€๊ณผ ๐Ÿ”„์ค‘๋ณต ์ž‘์—… ๋ฐœ์ƒ

โœ… ๊ทธ๋ž˜์„œ ์ด๋ ‡๊ฒŒ ํ•˜๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ตฌ์กฐ์™€ ๋ฐ์ดํ„ฐ๋„ Prisma๋ฅผ ํ†ตํ•ด ๋“ฑ๋ก, ์‚ญ์ œ, ์ˆ˜์ •ํ•˜๋„๋ก ๊ด€๋ฆฌ
  • Prisma ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๊ณผ ์‹œ๋”ฉ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ™œ์šฉํ•ด DB ์ƒํƒœ๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ์œ ์ง€
  • ์ด๋ฅผ ํ†ตํ•ด Supabase์™€ Prisma ๊ฐ„ ์Šคํ‚ค๋งˆ ๋ฐ ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ์ตœ์†Œํ™”

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์—์„œ ๋ฐ์ดํ„ฐ์™€ ์Šคํ‚ค๋งˆ๋ฅผ Prisma๊ฐ€ ์ „๋‹ด ๊ด€๋ฆฌํ•˜๋ฏ€๋กœ,
์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ณ  ์•ˆ์ •์ ์ธ DB ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Prisma Seed Script ์ž‘์„ฑ ๋ฐ ์‹คํ–‰ ์‹ค์Šต

1. script ํด๋”์— seed.ts ํŒŒ์ผ ์ƒ์„ฑ

์Šคํฌ๋ฆฝํŠธ ์ƒ์„ฑ

์™œ ํŒŒ์ผ๋ช…์„ seed๋ผ๊ณ  ํ• ๊นŒ์š”?

  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๋Š” ์ž‘์—…์„ ์‹œ๋”ฉ(seeding)์ด๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค.
  • seed.ts๋‚˜ seed.js ํŒŒ์ผ์€ ํ”„๋กœ์ ํŠธ ์‹œ์ž‘ ์‹œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ๊ธฐ๋ณธ ๋ฐ์ดํ„ฐ(์‚ฌ์šฉ์ž, ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ ๋“ฑ)๋ฅผ ๋„ฃ๊ธฐ ์œ„ํ•œ ์Šคํฌ๋ฆฝํŠธ ํŒŒ์ผ ์ด๋ฆ„์˜ ๊ด€๋ก€์ž…๋‹ˆ๋‹ค.

2. prisma.[๋ชจ๋ธ๋ช…].create ํ˜•์‹์œผ๋กœ ๋ฐ์ดํ„ฐ ์ƒ์„ฑ ์ฝ”๋“œ ์ž‘์„ฑ

// seed.ts
import { prisma } from "../lib/prisma.js";

async function main() {
  // User ์ƒ์„ฑ
  const user1 = await prisma.user.create({
    data: {
      userId: "user01",
      password: "password123",
      name: "ํ™๊ธธ๋™",
    },
  });

  // Project ์ƒ์„ฑ (managerId๋Š” user1.id๋กœ ์—ฐ๊ฒฐ)
  const project1 = await prisma.project.create({
    data: {
      projectId: "project01",
      progress: 0,
      deadline: new Date("2025-12-31"),
      managerId: user1.id,
    },
  });

  // Task ์ƒ์„ฑ (userId์™€ managerId๋Š” user1.id, projectId ์—ฐ๊ฒฐ)
  const task1 = await prisma.task.create({
    data: {
      title: "์ฒซ ๋ฒˆ์งธ ์ž‘์—…",
      desc: "ํ…Œ์ŠคํŠธ์šฉ ์ž‘์—… ์„ค๋ช…",
      status: "To Do",
      projectId: project1.id,
      userId: user1.id,
      managerId: user1.id,
    },
  });

  // Comment ์ƒ์„ฑ (userId, taskId ์—ฐ๊ฒฐ)
  await prisma.comment.create({
    data: {
      comment: "์ฒซ ๋ฒˆ์งธ ๋Œ“๊ธ€์ž…๋‹ˆ๋‹ค.",
      userId: user1.id,
      taskId: task1.id,
    },
  });

  console.log("์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ถ”๊ฐ€๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
}

main()
  .catch((e) => {
    console.error(e);
    process.exit(1);
  })
  .finally(async () => {
    await prisma.$disconnect();
  });

3. ts-node๋ฅผ ์ด์šฉํ•ด seed ์Šคํฌ๋ฆฝํŠธ ์‹คํ–‰

node --loader ts-node/esm ./src/scripts/seed.ts

JavaScript ํŒŒ์ผ ์‹คํ–‰ ๋ฐฉ๋ฒ•

  • JS ํŒŒ์ผ์ธ ๊ฒฝ์šฐ ts-node ์—†์ด ์•„๋ž˜ ๋ช…๋ น์–ด๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
node ./src/scripts/seed.js

4. npx prisma studio ๋ช…๋ น์–ด๋กœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋ฐ์ดํ„ฐ ํ™•์ธ

โœ… ์š”์•ฝ ์ •๋ฆฌ

1. ์ดˆ๊ธฐ ๋ฐ์ดํ„ฐ(์‹œ๋“œ ๋ฐ์ดํ„ฐ)๋Š” Seed Script๋กœ ๋ฏธ๋ฆฌ ๋„ฃ๊ธฐ

  • ๊ธฐ๋ณธ ์„ค์ •, ๊ด€๋ฆฌ์ž ๊ณ„์ •, ํ…Œ์ŠคํŠธ์šฉ ์ƒ˜ํ”Œ ๋ฐ์ดํ„ฐ ๋“ฑ์„ ์ดˆ๊ธฐํ™”ํ•  ๋•Œ ์‚ฌ์šฉ
  • ๊ฐœ๋ฐœ/ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๋น ๋ฅด๊ฒŒ ์ค€๋น„ํ•˜๊ณ  ํŒ€์› ๊ฐ„ ํ™˜๊ฒฝ ํ†ต์ผ ๊ฐ€๋Šฅ
  • DB ์ƒํƒœ๋ฅผ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค์–ด ์˜ค๋ฅ˜ ๊ฐ€๋Šฅ์„ฑ ๊ฐ์†Œ

์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ํ•œ ๋ฒˆ์— ๋„ฃ๊ธฐ: createMany ์‚ฌ์šฉ ์˜ˆ์‹œ

await prisma.user.createMany({
  data: [
    { userId: "user01", password: "pass01", name: "ํ™๊ธธ๋™" },
    { userId: "user02", password: "pass02", name: "๊น€์ฒ ์ˆ˜" },
    { userId: "user03", password: "pass03", name: "์ด์˜ํฌ" },
  ],
  skipDuplicates: true, // ์ค‘๋ณต๋œ ๋ฐ์ดํ„ฐ๋Š” ๋ฌด์‹œ
});

createMany๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ๋ฅผ ํ•œ ๋ฒˆ์— ํšจ์œจ์ ์œผ๋กœ ์‚ฝ์ž… ๊ฐ€๋Šฅ

skipDuplicates ์˜ต์…˜์œผ๋กœ ์ค‘๋ณต ๋ฐ์ดํ„ฐ ์‚ฝ์ž… ๋ฐฉ์ง€ ๊ฐ€๋Šฅ

2. ๊ทธ ์ดํ›„ ๋ฐ์ดํ„ฐ๋Š” API๋ฅผ ํ†ตํ•ด ์ƒ์„ฑ/์ˆ˜์ •ํ•˜๊ธฐ

  • ์šด์˜ ๋ฐ์ดํ„ฐ๋Š” API๋ฅผ ํ†ตํ•ด CRUD ์ž‘์—… ์ˆ˜ํ–‰
  • ์ง์ ‘ DB์— ๋„ฃ๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ, ๊ถŒํ•œ ๊ด€๋ฆฌ, ํŠธ๋žœ์žญ์…˜ ์ฒ˜๋ฆฌ์— ์œ ๋ฆฌ
  • ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ๊ถŒํ•œ ์ฒดํฌ ์ ์šฉ ๊ฐ€๋Šฅ

์ •๋ฆฌ

๊ตฌ๋ถ„๋ฐฉ๋ฒ•์ด์œ 
์ดˆ๊ธฐ ํ•„์ˆ˜ ๋ฐ์ดํ„ฐSeed Scriptํ™˜๊ฒฝ ์ดˆ๊ธฐํ™”, ๊ธฐ๋ณธ๊ฐ’ ์„ธํŒ…
์šด์˜ ๋ฐ์ดํ„ฐAPI / ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜๊ถŒํ•œ ๊ด€๋ฆฌ, ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ, ์•ˆ์ •์  ์šด์˜

๋งˆ์น˜๋ฉฐ

Prisma ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜๊ณผ ์‹œ๋”ฉ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ํ™œ์šฉํ•˜๋ฉด
๋ฐ์ดํ„ฐ์™€ ์Šคํ‚ค๋งˆ๋ฅผ ์ผ๊ด€๋˜๊ฒŒ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ์–ด,
Supabase์™€์˜ ๋™๊ธฐํ™” ๋ฌธ์ œ๋ฅผ ์ค„์ด๊ณ  ์•ˆ์ •์ ์ธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โš ๏ธ ์ง์ ‘ DB๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋Œ€์‹  Prisma๋ฅผ ํ†ตํ•ด ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

profile
๋‹จ์ˆœ ์‚ฌ์šฉ์ž๊ฐ€ ์•„๋‹Œ, ์ดํ•ดํ•˜๊ณ  ๋งŒ๋“œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜๊ธฐ ์œ„ํ•œ ๊ธฐ๋ก.

0๊ฐœ์˜ ๋Œ“๊ธ€