어느날, PlanetScale의 무료 플랜 종료 소식이 다가왔다.
얼른 이사가라고 수 통의 이메일을 받았다.
억장 와르르멘션이었다.
편리하게 사이드 프로젝트 데이터베이스를 무료 호스팅하고 있었는데 대안이 필요했다.
planetscale alternative free를 검색해보면 PostgreSQL은 supabase, neon SQLite은 turso, MySQL은 cockroach 등 선택지가 있다.
모두 매력적인 선택지이지만, Vercel Postgres에서 neon을 래핑해서 서빙하다는 소식, 또 요즘 핫한 PostgreSQL를 경험해보고 싶은 마음에 neon을 새둥지로 이사 가보기로 했다.
pgloader로 데이터 옮기기
pgloader는 PostgreSQL 데이터를 등록할 수 있는 오픈소스이다.
이를 활용해 MySQL 데이터를 PostgresSQL로 쉽게 옮길 수 있다.
MacOS 기준, brew로 쉽게 설치를 할 수 있으며,
brew install pgloader
아래 명령어로 MySQL에서 PostgreSQL로 데이터 마이그레이션 할 수 있다.
pgloader --with "quote identifiers" mysql://myuser@myhost/dbname pgsql://pguser@pghost/dbname
자세한 옵션명을 하나 하나 정리하면 아래와 같다.
--with "quote identifiers"
카멜 케이스를 그대로 유지시키는 명령어이다.
그게 아니면 테이블명도 그렇고 칼럼명도 그렇고 스네이크 케이스로 적용된다.
자세한 내용은 공식문서 참고하면 된다.
mysql://myuser@myhost/dbname
우선 PlanetScale CLI를 통해서 로컬 호스트로 DB를 접근할 수 있다.
pscale login
pscale connect mildvu --port 8080
따라서 MySQL 데이터베이스 호스트는 아래같이 입력하면 된다.
mysql://127.0.0.1:8080/mildvu"
pgsql://pguser@pghost/dbname
neon 대시보드에서 데이터베이스 connection string을 받아오면 된다.
마이그레이션 할 땐 Pooled connection 옵션을 적용하지 않아도 괜찮다.
추가적으로 endpoint
옵션을 넣어줘야 하는데 ep-xxx
부분을 잘 찾아서 입력해주면 된다.
postgresql://mildvu_owner:endpoint=ep-xxx;[password]@ep-xxx.ap-southeast-1.aws.neon.tech/main?sslmode=require
최종 형태 및 결과물
메모장에서 위 내용을 잘 조합하고, 이제 터미널에 명령어를 입력하면 된다.
pgloader --with "quote identifiers" mysql://127.0.0.1:8080/mildvu "postgresql://mildvu_owner:endpoint=ep-xxx;[password]@ep-xxx.ap-southeast-1.aws.neon.tech/main?sslmode=require"
그러면 아래 같은 리포트를 볼 수 있다.
크흠.. 나의 데이터는 사실 117.3KB 밖에 되지 않았다.. 작지만 소중해
neon의 Tables에도 데이터가 잘 이전된 것을 확인 할 수 있다 ✨
neon 스키마 이름 변경
현재 데이터는 기존 데이터베이스명인 “mildvu”로 neon의 스키마로 이관이 되었지만, prisma는 이름이 “public”인 스키마를 접근하게 되는 것 같다.
이래 저래 시도해봤지만 결국 스키마명을 수정하여 문제를 해결했다.
neon 대시보드에 있는 SQL Editor
에서 아래 명령어로 스키마명을 변경할 수 있다.
ALTER SCHEMA "mildvu" RENAME TO "public"
prisma 설정
prisma에서 neon의 사용법은 공식문서 가이드 대로 진행하면 된다.
prisma env
neon 대시보드에 있는 Connection string을 가져오면 된다.
여기서는 Pooled connection을 활성화시키자.
DATABASE_URL=postgresql://mildvu_owner:[password]@ep-ancient-firefly-a1fdd8wb-pooler.ap-southeast-1.aws.neon.tech/main?sslmode=require
prisma schema
MySQL 대신 PostgreSQL을 명시하면 된다.
generator client {
provider = "prisma-client-js"
- previewFeatures = ["referentialIntegrity"]
+ previewFeatures = ["driverAdapters"]
}
datasource db {
- provider = "mysql"
+ provider = "postgresql"
url = env("DATABASE_URL")
- referentialIntegrity = "prisma"
+ relationMode = "prisma"
}
생각보다 큰 충돌은 없었다.
추가적으로 문자열 관련 어노테이션을 수정해주면 되었다.
@db.MediumText
, @db.LongText
→ @db.VarChar()
prisma client
변경된 스키마 바탕으로 prisma client을 생성하고,
npx prisma generate
가이드 대로 코드를 수정하면 된다.
import { neonConfig, Pool } from '@neondatabase/serverless';
import { PrismaNeon } from '@prisma/adapter-neon';
import { PrismaClient } from '@prisma/client';
import ws from 'ws';
declare global {
var _prisma: PrismaClient | undefined;
}
neonConfig.webSocketConstructor = ws;
const connectionString = `${process.env.DATABASE_URL}`;
const pool = new Pool({ connectionString });
const adapter = new PrismaNeon(pool);
const _prisma = global._prisma || new PrismaClient({ adapter });
if (process.env.NODE_ENV === 'development') {
global._prisma = _prisma;
}
export default _prisma;
npx prisma generate
을 하지 않으면 타입 에러, 런타임 에러가 발생하니 꼭 유의하도록 하자.
맺으면서
사이드 프로젝트를 유지보수하는 것이 쉽지가 않는 것 같다.
특히 인프라 이슈가 있을 땐 진짜 맨땅에 헤딩이다.
하지만 덕분에 더 다양한 serverless 플랫폼을 알게 되었고, DB와도 조금 더 친해졌다.
앞으로 더 친해져 봐요 우리…
한편으로 Vercel이 무료 플랜을 종료한다면 어떻하지 머리가 아찔해졌다.