소개
Supabase팀은 최근 Declarative Schemas 기능을 새롭게 선보였습니다.
지금까지의 테이블 스키마 관리 방식은 migration 파일을 통해 전체 테이블 형상의 변경을 기술하는 방식이였습니다.
만일 새로운 컬럼을 추가하려면 alter
구문으로 해당 테이블에 변경 사항을 새로운 migration 파일에 기술해 주고 local에서 테스트 한 뒤 remote에 업데이트하는 방식입니다.
실제 작업을 해 보면 이러한 방식은 많은 문제점을 가지고 있습니다.
먼저 테이블의 현재의 형상 파악이 코드에 녹아 있지 않습니다. Migration 파일을 사용해 imperative한 테이블 변경 정보만을 가지고 있기 때문에 최종 형상에 대한 정보는 별도의 툴을 사용해서 확인해야 합니다.
특별히 복수의 개발자가 데이터 베이스를 변경하고자 할 때, 상황은 더욱 복잡해 집니다.
Declarative Schemas 셋업
새로운 방식을 경험해 보려면 먼저 다음과 같이 remote나 local postgres로 부터 전체 스키마 정보를 가져옵니다.
supabase db dump > supabase/schemas/prod.sql
지금 까지 작업한 내용이 많을 것 임으로 이를 적절히 기능별로 분리해 주는 것이 좋습니다.
https://github.com/swcho/supabase-nextjs-todo-list/tree/fbdb03ad15261bebebe06a1945ab96257ba1f520/supabase/schemas
Supabase CLI는 supabase/schemas
폴더에 있는 파일의 순서에 따라 실행하기 때문에 다음과 같이 적절한 순서 prefix와 함께 기능이름을 적어 주면 좋습니다.
supabase/schemas
├── 0000_prod.sql
├── 0050_invitations.sql
└── 0051_invitations_functions.sql
기능별로 파일을 분리하고 나서 다음 명령을 사용하여 migration 파일을 생성해 봅니다.
npx supabase stop
npx supabase db diff -f SHOULD_NOT_GENERATED
supabase/schema
폴더의 DDL과 local 환경의 postgres 스키마와의 차이에 따른 migration 파일을 생성할 수 있습니다.
다만, supabase stop
명령으로 local 인스턴스 사용을 중지해야하는 번거로움이 있어 아쉬운 부분입니다.
만일 차이가 발생하면 {날짜}_SHOULD_NOT_GENERATED.sql
형식으로 파일이 생겨야 하는데 원본 파일에서 기능별로 DDL을 분리한 것이기 때문에 생성이 되지 않음을 확인하면서 작업하면 됩니다.
Declarative Schemas Workflow
https://github.com/swcho/supabase-nextjs-todo-list/commit/209cd6470550b5c6fd6b41369d45016baa3ca20e#diff-1760652d23267e0d28bb5aa320a0ee474b6bbc2e5e3fd9beb948f53a4f7f923bR11
테이블에 컬럼을 추가하고 싶다면, 단순히 supabase/schema
폴더에 정의한 DDL의 사양을 변경해 주면 됩니다.
이후 대략 다음과 같은 스크립트를 통해 migration을 생성하고 local에 변경 사항을 적용할 수 있습니다.
#!/bin/bash
# Take first argument as migration file name
MIGRATION_FILE=$1
if [ -z "$MIGRATION_FILE" ]; then
echo "Usage: $0 <migration_file>"
exit 1
fi
npx supabase stop # 먼저 local 인스턴스를 멈추고
npx supabase db diff -f $MIGRATION_FILE # migration 파일을 생성하고
npx supabase start -x vector # 다시 local 인스턴스를 시작하고
npx supabase migration up # migration 파일의 변경사항을 적용합니다.
Migration 파일 생성은 djrobstep/migra 툴을 사용하기 때문에 migra 툴의 한계와 문제점을 그대로 계승합니다.
따라서 Known caveats의 내용을 잘 숙지할 필요가 있습니다.
마치며
그간 toy project를 구현하면서 supabase db 변경 작업에 대한 빠르고 쉬운 방법을 찾기위해 고민했습니다.
Prisma와 같은 ORM을 사용해 보고도 싶었지만 복잡도와 추상화 단계를 추가하지 않는 방향이 옳다고 판단했습니다.
하지만 RLS대신 함수기반의 API 호출과 테이블 스키마의 변경 작업을 migration 파일 작성만으로 하는 것은 여간 번거롭고 고된 작업이 아닐 수 없었습니다.
현재의 스키마 상태를 파악하고 적절한 변경 구문을 작성하는 것이 많이 피로해 질 때 즈음 Declarative schema 기능은 가뭄의 단비 같은 소식이였습니다.
아직 아쉬운 부분이 없지는 않으나, Supabase 팀이 개발자의 pain point를 정확히 이해하고 대응하고 있다는 점에서 앞으로도 많을 발전을 기대해 볼 수 있을 것 같습니다.