저번에 Prisma 를 설치하고 잠깐이나마 알아보는 시간을 가져보았다.
이전에는 데이터소스에 대해 이야기를 해보았는데...
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
데이터소스는 Prisma 에게 데이터베이스의 주소 (URL)와 종류 (provider) 에 대해 알려주는 작업을 한다.
이번에는 client 에 대해 이야기하는 시간을 가지겠다.
generator client {
provider = "prisma-client-js"
}
Client 는 기본적으로 어떤 방식으로 데이터베이스와 상호작용하는 것이다.
현재로서 우리의 데이터베이스는 아무것도 없고 비어있다.
그리하여, client 를 생략하고 Prisma Migrate 로 넘어가볼 것이다.
시작하기 앞서, VSCode 의 extensions 를 열어서 prisma 라는 익스텐션을 설치해준다.
이 익스텐션은 파일에 색을 입히고, 자동완성 기능도 있으며 매우 편리한 기능들을 가지고 있다.
그리고 이제 Movie Model 를 만드는 것으로 넘어갈 수 있다!
우리의 Movie 는 title 과 year 를 가지고 있는데, 추가적으로 id 를 적어준다.
const typeDefs = gql`
type Movie {
id: Int
title: String
year: Int
}
type Query {
movies: [Movie]
movie: Movie
}
type Mutation {
createMovie(title: String!): Boolean
deleteMovie(title: String!): Boolean
}
`;
그럼 이제 Movie 를 데이터베이스에게 어떻게 설명할 수 있을까???
간단하다!
Prisma 공식 문서로 가면 어떻게 하면 되는지 구체적으로 나와있다.
출처 : https://www.prisma.io/docs/getting-started/quickstart
GraphQL 처럼 생겼는데, 하지만 GraphQL 은 아니다.
그래서 우리의 프로젝트에서 첫 model 를 만들어보자!
그럼 schema.prisma 파일에서 model Movie 를 추가해보면...
model Movie {
id
title
year
}
예를 들어 위의 이미지를 참고해보면, id 는 @id 라고 표시할거다.
그리고 default 값을 설정할 수 있고, autoincrement 함수를 실행할 것이다.
이 함수는 1, 2, 3처럼 자동으로 숫자를 1씩 증가시켜줄 거다. (자동 증가인 것 이다.)
그리하여 위의 Model 를 참고해서 작성해보면...
model Movie {
id Int @default(autoincrement()) @id
title String
year Int
}
이게 Model 를 적는 방식이다.
다음으로 createdAt 와 updatedAt 를 추가적으로 추가해준다.
타입으로는 DateTime 을 갖고 있고 각자 다른 기능들을 탑재하고 있다.
model Movie {
id Int @default(autoincrement()) @id
title String
year Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
@default(now( )) 의 기능은 모델이 생성되었을 때 기본적으로 데이터베이스에 now, 즉 현재 시간을 추가하는 것이다. (데이터베이스에 movie 가 생성되는 시간을 말한다.)
@updatedAt 은 movie 를 저장할 때마다 매번 날짜를 저장하게 된다.
DateTime 라는 타입은 Prisma 에 포함되어 있다.
위의 전부다 required 이다.
그런데 Movie 에서 required 가 아닌 field 를 지닐 수 있다.
model Movie {
id Int @default(autoincrement()) @id
title String
year Int
genre String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
genre 필드를 만들어줄 때, String 타입끝에 ? 를 추가해주는데 이게 바로 required 가 아니라고 표시하는 것이다.
그럼 이제 이걸 데이터베이스에 넣을 수 있을까?
바로 이때 prisma migrate 를 실행할 때다!
이게 prisma migrate 의 명령어이다.
$ npx prisma migrate dev --name init
'--name init' 은 불필요하다. 그 이유는 나중에 migration 에 줄 수 있다.
그래서 밑에 있는 커맨드를 우리의 프로젝트에 설치해준다.
$ npx prisma migrate dev
migrate dev 라고 하면 개발 환경에서 작업 중이라는 의미로 받아들여 진다.
테스트 데이터베이스를 사용할 때, migrate dev 라고 할 때다.
아 그리고 설치를 했는데 다음과 같이 오류가 생기면...
.env 파일로 가서...
이 randompassword 부분을 pgAdmin 4 에서 지정해둔 비밀번호로 바꿔준다.
그리고 다시 설치하면...
이름은 init 이라고 지어준다.
프로젝트를 확인해보면...
migrations 라는 폴더가 생기고, timestamp, 내 이름 (init) 그리고 migration.sql 파일이 생겼다.
그리고 터미널을 보면 "Running generate..." 이라고 뜨는데, prisma migrate dev 를 실행한 경우에 자동으로 prisma client 를 얻게 된다.
prisma migrate 는 자체적으로 Prisma Client 를 생성하지 않는다.
그러니까 prisma migrate 는 데이터베이스의 형태를 변형시켜준다.
migrations 폴더 안에 migration.sql 파일을 보면...
-- CreateTable
CREATE TABLE "Movie" (
"id" SERIAL NOT NULL,
"title" TEXT NOT NULL,
"year" INTEGER NOT NULL,
"genre" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Movie_pkey" PRIMARY KEY ("id")
);
SQL 코드는 보다시피 Movie 라는 표를 생성해준다.
보다시피 이건 PostgreSQL 을 위한 SQL 코드다.
그래서 Prisma 는 우리가 schema.prisma 에서 작성한 코드를 토대로 migration.sql 의 SQL 코드로 변환해 주는 것이다.
그리고 migration 을 데이터베이스에도 적용시켜준 것이다.