prisma 란?

Posted by : on

Category : nextJs


prisma란

  • Prisma: Node.js 기반의 ORM(Object-Relational Mapping) 도구로, 데이터베이스와의 상호 작용을 단순화하고 개발 생산성을 높이는 데 도움을 주는 도구
  • SQL 쿼리를 직접 작성하는 대신 자바스크립트 코드로 쿼리를 작성할 수 있게 해주며, 타입 세이프한 쿼리 작성성을 통해 런타임 에러를 방지
  • 타입 세이프 쿼리: 쿼리를 자바스크립트 코드로 작성함으로써 타입 에러를 사전에 방지
  • 자동 마이그레이션: 데이터베이스 스키마 변화를 감지하고 자동으로 마이그레이션을 처리하여 스키마 관리를 간소화
  • 강력한 문법: 복잡한 쿼리 및 데이터베이스 관계를 다루기 위한 강력한 문법 제공

Prisma 개념 (구성 요소)

  • Prisma Client: Node.js & TypeScript용 쿼리 작성 클라이언트
  • Prisma Migrate: 마이그레이션 시스템
  • Prisma Studio: 데이터베이스의 데이터를 보고 편집하는 GUI
  • 개발자가 직접 SQL문을 작성하지 않아도, 데이터베이스와 상호작용할 수 있는 ORM
  • 타 ORM과는 달리, 자체적인 스키마 문법 제공하여 직접 DB 마이그레이션, 클라이언트 코드 생성 등 작업 가능
  • 위에 언급한 간편한 CLI, Prisma Studio 등 편리한 GUI 도구 제공하여 생산성 향상

Prisma 기능

  • Prisma Client: 데이터베이스와 상호 작업하기 위한 자바스크립트 코드를 자동으로 생성해주는 도구
  • 스키마 정의: 데이터베이스 스키마를 정의하고 관리
  • DB 마이그레이션: 데이터베이스 스키마 변화를 추적하고 적용할 수 있는 마이그레이션 기능 제공
  • DB 관계 정의: 복잡한 데이터베이스 관계를 정의하고 쿼리 기능 제공
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[]
}

스키마

  • 모델 (Model): 모델은 데이터베이스의 특정 테이블이나 컬렉션과 대응. Prisma에서 모델을 정의하면 해당 모델에 대한 데이터베이스 테이블이나 컬렉션이 생성됨

  • 필드 (Field): 모델 내에서 필드는 해당 모델이 가지는 데이터 속성을 나타냄. 각 필드는 데이터 타입과 제약 조건을 가질 수 있음

  • 관계 (Relation): Prisma에서 관계는 모델 간의 연관을 나타냄. 두 테이블 간의 외래 키(Foreign Key)를 관리하고 연결된 데이터를 쿼리 가능

Pasted image prisma.png


사용법

세팅

  1. Prisma 설치 후, Prisma Client 인스턴스화 해야 함. 세팅은 아래 단계를 따라 적용 Prisma Schema에 generator 정의:
generator client {
  provider = "prisma-client-js"
}
  1. prisma/client 패키지 설치 후 prisma generate 실행:
yarn add @prisma/client
prisma generate
  1. Prisma Client를 인스턴스화 해서 사용:
import { PrismaClient } from '@prisma/client'

const prisma = new PrismaClient()
// `prisma`를 사용하여 데이터베이스에서 데이터를 읽고 쓸 수 있습니다.


CRUD

create
  • Prisma로 데이터를 생성하기 위해서는 create API 사용
const user = await prisma.user.create({
  data: {
    email: 'elsa@prisma.io',
    name: 'Elsa Prisma',
  },
});
  • Prisma로 데이터를 조회하기 위해서는 findMany 또는 findUnique와 같은 메서드 사용
const users = await prisma.user.findMany({
  where: {
    age: {
      gte: 18,
    },
  },
  orderBy: {
    name: 'asc',
  },
  include: {
    posts: true,
  },
  select: {
    id: true,
    name: true,
  },
});

where, orderBy, include, select 등의 옵션으로 쿼리 조건 설정 가능

update

하나만 수정하기 위해서는 update 메서드를 사용하고, 여러 레코드를 한 번에 업데이트하려면 updateMany 사용

const updatedUser = await prisma.user.update({
  where: {
    id: 1,
  },
  data: {
    name: 'Updated Name',
  },
});
delete

데이터를 삭제하기 위해서 delete 메서드 사용

const deletedUser = await prisma.user.delete({
  where: {
    id: 1,
  },
});

하나만 삭제하기 위해서는 delete 메서드를 사용하고, 여러 레코드 삭제를 위해서는 deleteMany 사용

const deleteUsers = await prisma.user.deleteMany({
  where: {
    email: {
      contains: 'prisma.io',
    },
  },
});

DB에 반영

마이그레이션

앞서 작성한 스키마를 DB에 반영하기 위해서는 마이그레이션 명령어를 작성해야 함

npx prisma migrate dev

//마이그레이션 파일에 --name 옵션을 사용하여 이름을 지정할 수 있음
npx prisma migrate dev --name init

마이그레이션 된 파일들은 prisma/migrations에 생성됨. 현재 날짜와 시간, 그리고 –name 문자열 조합으로 생성됨

prisma
 └── schema.prisma
 └── migrations
      └── 20230331052907_init
      └── migration.sql
  • 해당 마이그레이션 파일은 직접 수정하면 안됨. 항상 prisma migrate 명령어를 통해서만 파일 생성 / 디비 수정이 가능함.
  • 마이그레이션 명령어를 통해 생성된 파일은 Prisma가 관리하며, 수정할 경우 예상치 못한 오류가 발생할 수 있음.
-- CreateTable
CREATE TABLE "User" (
  "id" TEXT NOT NULL,
  "email" TEXT NOT NULL,
  "name" TEXT,
  CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);

-- CreateTable
CREATE TABLE "Post" (
  "id" TEXT NOT NULL,
  "title" TEXT NOT NULL,
  "content" TEXT NOT NULL,
  "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
  "userId" TEXT,
  CONSTRAINT "Post_pkey" PRIMARY KEY ("id")
);

-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");

-- CreateIndex
CREATE INDEX "Post_userId_idx" ON "Post"("userId");

-- AddForeignKey
ALTER TABLE "Post" ADD CONSTRAINT "Post_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;

확인

확인은

npx prisma studio

로 해주면 된다.

Seed - 초기 데이터나 테스트 데이터를 넣는 과정

Prisma.schema 모델링을 먼저 해주고 마이그레이션을 해준다.

npx prisma migrate dev --name init

그다음 아래 순서를 따른다.

  1. package.json에 seed 스크립트 추가 yarn add –dev ts-node 추가
    "prisma": {
      "seed": "ts-node --compiler-options {\"module\":\"CommonJS\"} prisma/seed.ts"
    }
    
  2. Prisma 폴더 내에 seed.ts 파일 생성 후, seed 코드 작성
const { PrismaClient } = require('@prisma/client');

const prisma = new PrismaClient();

async function seedData() {
  // seed 코드 작성
}

async function main() {
  await seedData();
}

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

  1. seed 함수
async function seedData() {
  data?.['DATA']?.map(async (store) => {
    const storeData = {
      phone: store.tel_no,
      address: store?.rdn_code_nm,
      lat: store?.y_dnts,
      lng: store?.x_cnts,
      name: store.upso_nm,
      category: store?.bizcnd_code_nm,
      storeType: store?.cob_code_nm,
      foodCertifyName: store?.crtfcc_gbn_nm,
    };
    
    const result = await prisma.store.create({
      data: storeData
    });

    console.log(result);
  });
}
  1. npx prisma로 데이터 시드 실행
    npx prisma db seed
    

에러

npx prisma migrate dev --name init
Environment variables loaded from .env
Prisma schema loaded from prisma\schema.prisma
Datasource "db": PostgreSQL database "postgres", schema "public" at "aws-0-ap-northeast-2.pooler.supabase.com"

하… 삽질 엄청했다 여기서 더이상 진행이 안돼서. 결론은 위 url을 아래처럼 바꿔주면 된다.

DATABASE_URL="postgresql://postgres.qkkdhukxhudwdxtmphqe:비밀번호@aws-0-ap-northeast-2.pooler.supabase.com:6543/postgres"

DATABASE_URL="postgresql://postgres.qkkdhukxhudwdxtmphqe:비밀번호@aws-0-ap-northeast-2.pooler.supabase.com"


About 유재석
유재석

개발자 유재석 입니다. Web Developer.

Email : jaeseok9405@gmail.com

Website : https://github.com/yoo94