티켓 스키마 마이그레이션

CloudflareBeginner
지금 연습하기

소개

기존 요청을 잃지 않으면서 티켓 서비스에 긴급도를 추가해야 합니다. 기존 행이 새 규칙을 만족하지 못하면 스키마 배포가 실패할 수 있습니다. 이 실습에서는 순서가 지정된 마이그레이션을 만들고 로컬에서 테스트한 다음, 티켓의 ID 와 제목을 보존하면서 동일한 파일을 원격 데이터베이스에 적용합니다.

이 실습은 제공된 초기 마이그레이션으로 독립적으로 시작합니다. D01 에서 다룬 데이터베이스 생성과 기본 SQL 을 전제로 하지만, 이전 VM 이나 데이터베이스는 사용하지 않습니다.

자신의 학습 계정과 새 VM 을 사용합니다. 먼저 설정 과정에서 Node.js 22.22.0 을 준비한 다음, /home/labex/project/ticket-database에서 프로젝트 전용 Wrangler 4.131.1 과 평가에 필요한 의존 항목을 npm install로 설치합니다. 직접 지정된 의존성 버전은 고정되어 있으며, 설치 과정에서 자체 lockfile 이 생성됩니다. 설정 과정에서는 클라우드 로그인이나 평가 대상 데이터베이스 작업을 실행하지 않습니다. 개인 컴퓨터에서는 프로젝트에서 npm install --save-dev wrangler@4.131.1을 실행해 동일한 Wrangler 버전을 설치합니다.

이 실습에서는 D1 Free allowances 범위 내의 작은 테스트용 레코드를 사용합니다. 기존 계정 사용량도 해당 한도에 포함됩니다. 구매한 도메인은 필요하지 않습니다. 리소스 삭제와 로그아웃이 모두 확인될 때까지 이 VM 을 유지합니다.

이 VM 을 인증하고 계정 선택하기

이 단계에서는 새 터미널을 자신의 학습 계정에 연결합니다. Dashboard 에 로그인하는 것만으로는 VM 이 인증되지 않습니다. D1 권한이 있어야 데이터베이스를 생성하고, SQL 을 변경하고, 데이터베이스를 삭제할 수 있습니다. 인증하기 전에 Background Access 를 포함한 실제 동의 페이지의 내용을 확인합니다.

준비된 프로젝트를 열고 버전이 고정된 CLI 를 확인합니다.

cd /home/labex/project/ticket-database
npx wrangler --version

4.131.1이 표시되어야 합니다. 디바이스 인증을 시작합니다. --device는 브라우저에 입력할 코드를 표시하고, --browser=false는 브라우저를 직접 선택할 수 있도록 합니다.

npx wrangler login --device --browser=false --scopes account:read user:read d1:write

브라우저에서 표시된 URL 을 열고 현재 코드를 입력합니다. 학습 계정과 권한을 확인한 뒤 인증을 승인합니다. 터미널에서 성공 메시지가 표시될 때까지 기다립니다. 비밀번호나 토큰을 프로젝트 파일에 붙여 넣지 마세요.

npx wrangler whoami --json

loggedIn: true인지 확인한 다음, 계정이 하나만 표시되더라도 계정의 nameid를 읽습니다. 사용할 계정의 ID 를 복사해 아래 설정에 입력합니다. 다음 셸 변수는 임의의 6 바이트 (16 진수 12 자) 를 사용해 다른 학습자의 실행과 이름이 충돌하지 않도록 합니다. here-document 는 JSON으로 표시된 두 줄 사이의 JSON 을 파일에 기록하며, 내부의 $RUN은 확장됩니다.

$schema 앞의 백슬래시는 이 JSON 키를 그대로 유지하며, $RUN 은 이번 실행의 고유 이름으로 확장됩니다.

RUN=labex-c04-d03-$(openssl rand -hex 6)
cat > wrangler.jsonc <<JSON
{
  "\$schema": "./node_modules/wrangler/config-schema.json",
  "name": "$RUN",
  "account_id": "YOUR_ACCOUNT_ID",
  "main": "src/index.js",
  "compatibility_date": "2026-09-15",
  "workers_dev": true,
  "preview_urls": false
}
JSON

블록을 실행하기 전에 YOUR_ACCOUNT_ID를 실제 계정 ID 로 바꿉니다. RUN을 계속 사용할 수 있도록 이 터미널을 열어 둡니다. name은 이번 실행을 식별하고, account_id는 클라우드 작업에 사용할 계정을 선택합니다. 이 파일은 일반 JSON 이며 JSONC 로도 유효합니다. 이 파일을 작성하는 것만으로 Worker 가 배포되지는 않습니다.

기존 티켓 데이터베이스 준비하기

이 단계에서는 애플리케이션 데이터베이스의 기존 버전을 준비합니다. 마이그레이션은 스키마 변경 내용을 설명하는 번호가 매겨진 SQL 파일입니다. Wrangler 는 적용된 파일명을 d1_migrations에 기록하므로, 이후 실행에서 완료된 작업과 대기 중인 작업을 구분할 수 있습니다. 설정 과정에서 이전 애플리케이션 버전인 0001_initial.sql을 제공합니다. 업그레이드는 직접 만듭니다.

삭제할 수 있는 클라우드 데이터베이스를 생성합니다. --binding DB는 애플리케이션 코드에서 사용할 짧은 이름을 지정하고, --update-config는 실제 이름과 UUID 를 wrangler.jsonc에 기록하며, --use-remote=false는 개발 작업을 로컬에서 수행하도록 합니다.

npx wrangler d1 create "$RUN-db" --binding DB --update-config --use-remote=false

생성된 이름과 ID 를 확인한 다음 저장된 바인딩을 살펴봅니다.

cat wrangler.jsonc

DB 항목에 이번 실행에서 생성한 데이터베이스의 이름이 있어야 합니다. 바인딩은 코드와 리소스 사이에 구성된 연결입니다. UUID 는 클라우드 데이터베이스를 식별하고, --local은 이 VM 에서 별도의 SQLite 데이터베이스를 사용합니다. SQL 명령에는 항상 --local 또는 --remote 중 하나를 지정합니다.

적용하기 전에 기존 스키마를 읽습니다.

cat migrations/0001_initial.sql

기존 티켓 두 개가 있고 priority 열은 없습니다. 다음 명령을 로컬 대상과 원격 대상에 각각 실행하고, 메시지가 표시되면 이 실습에서 만든 데이터베이스인지 확인합니다.

npx wrangler d1 migrations apply DB --local
npx wrangler d1 migrations apply DB --remote

행과 적용된 마이그레이션 상태를 확인합니다.

npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id; SELECT name FROM d1_migrations ORDER BY id;"

기존 티켓 두 개가 모두 존재해야 하며, 적용된 마이그레이션은 0001_initial.sql이어야 합니다. 적용된 마이그레이션은 이력입니다. 이후 변경 사항은 기존 이력 파일을 수정하지 말고 새 파일로 만듭니다.

로컬에 제약 조건이 있는 우선순위 추가하기

이 단계에서는 테이블을 삭제하지 않고 기존 티켓에 기본 우선순위를 지정합니다. ALTER TABLE ... ADD COLUMN은 테이블을 현재 상태에서 변경합니다. 기존 행에 추가하는 NOT NULL 열에는 기존 행에 적용할 유용한 기본값이 필요합니다. CHECK는 우선순위를 normal 또는 urgent로 제한합니다.

다음 번호의 마이그레이션을 만듭니다.

npx wrangler d1 migrations create DB add_priority

이 새 프로젝트에서는 migrations/0002_add_priority.sql이 생성됩니다. 출력에서 파일명이 이와 같은지 확인합니다. 새 파일에 변경 내용을 기록합니다.

cat > migrations/0002_add_priority.sql <<'SQL'
ALTER TABLE tickets ADD COLUMN priority TEXT NOT NULL DEFAULT 'normal' CHECK(priority IN ('normal','urgent'));
SQL

대기 중인 마이그레이션을 나열한 다음 로컬에만 적용합니다.

npx wrangler d1 migrations list DB --local
npx wrangler d1 migrations apply DB --local

기존 티켓 두 개의 prioritynormal로 설정되어야 합니다. 긴급 티켓을 하나 추가하고 조회합니다.

npx wrangler d1 execute DB --local --command "INSERT INTO tickets (id, subject, source, priority) VALUES (3, 'Service unavailable', 'local', 'urgent'); SELECT id, subject, priority FROM tickets ORDER BY id;"

허용 범위를 벗어난 우선순위는 조용히 테이블에 입력되지 않고 실패해야 합니다.

npx wrangler d1 execute DB --local --command "UPDATE tickets SET priority = 'critical' WHERE id = 3;"

CHECK constraint failed가 표시되어야 합니다. 이 의도된 오류로 인해 티켓 3 의 우선순위는 urgent로 유지됩니다. 원격 데이터베이스에서 PRAGMA table_info(tickets)를 읽어 클라우드 스키마가 아직 이전 버전인지 확인합니다.

npx wrangler d1 execute DB --remote --command "PRAGMA table_info(tickets);"

원격 데이터베이스에는 아직 priority가 없습니다. 로컬에서 마이그레이션이 성공해도 클라우드가 업데이트되지는 않습니다.

테스트한 마이그레이션을 원격에 적용하기

이 단계에서는 검토한 동일한 파일을 원격 데이터베이스에 배포합니다. 확인하기 전에 대기 중인 작업을 살펴봅니다.

npx wrangler d1 migrations list DB --remote
npx wrangler d1 migrations apply DB --remote

0002_add_priority.sql만 대기 중이어야 합니다. 기존 행은 유지됩니다. 원격 데이터베이스에 긴급 티켓을 추가한 다음 데이터와 마이그레이션 이력을 모두 확인합니다.

npx wrangler d1 execute DB --remote --command "INSERT INTO tickets (id, subject, source, priority) VALUES (3, 'Service unavailable', 'remote', 'urgent'); SELECT id, subject, priority FROM tickets ORDER BY id; SELECT name FROM d1_migrations ORDER BY id;"

티켓 1 과 2 의 제목은 그대로 유지되고 prioritynormal이어야 합니다. 티켓 3 의 priorityurgent여야 합니다. 번호가 매겨진 두 파일이 모두 기록되어야 합니다. 다시 적용 명령을 실행합니다.

npx wrangler d1 migrations apply DB --remote

대기 중인 마이그레이션이 없다고 표시되고 행은 변경되지 않아야 합니다. 이것이 이력 테이블이 중요한 이유입니다. 배포를 다시 실행해도 완료된 파일은 다시 실행되지 않습니다. Dashboard 에서 이번 실행의 D1 데이터베이스를 열고 스키마/테이블 화면을 확인해 새 열과 CLI 결과가 일치하는지 살펴봅니다. 해당 화면에서 스키마를 수정하지 마세요.

D1 Studio 에서 마이그레이션된 priority 열

이 예시는 기존 티켓 두 개의 기본 우선순위가 normal이고 새 원격 티켓의 우선순위가 urgent인 모습을 보여 줍니다. 생성된 데이터베이스 이름은 이 예시 실행을 식별하므로 실제 이름은 다릅니다. 위의 SQL 쿼리, 마이그레이션 기록과 제약 조건 검사로 결과를 확인하며, 스크린샷은 시각적 참고 자료입니다.

임시 리소스 삭제하기

이 단계에서는 VM 이 인증된 상태에서 이번 실습의 리소스만 삭제합니다. 먼저 모든 기능 확인을 완료합니다. 삭제 확인이 끝날 때까지 설정 파일을 유지합니다.

npx wrangler d1 delete DB

프롬프트의 내용을 확인하고 이번 실행에서 생성한 데이터베이스만 삭제하는지 확인합니다. 그런 다음 데이터베이스를 나열합니다.

npx wrangler d1 list --json

성공적인 응답에 기록해 둔 데이터베이스 이름과 UUID 가 없어야 합니다. 다른 리소스는 남아 있어도 됩니다. 인증 또는 네트워크 오류만으로는 삭제 여부를 판단할 수 없습니다. 액세스 문제를 해결한 다음 계속하기 전에 다시 조회합니다. 로그인 상태를 유지한 채 이 단계의 확인을 실행합니다.

이 VM 의 인증 종료하기

이 단계에서는 독립적인 삭제 확인이 통과한 후에만 인증을 종료합니다. 로그아웃하면 이 VM 에 저장된 Wrangler 인증 정보가 삭제됩니다. VM 을 닫는 것만으로는 클라우드 리소스가 정리되지 않습니다.

npx wrangler logout
npx wrangler whoami --json

loggedIn: false가 표시되어야 합니다. 인증되지 않은 이 조회 명령은 종료 코드가 0 이 아닐 수 있습니다. 구조화된 응답에 실제로 로그아웃 상태가 명시된 경우에만 정상적인 결과입니다. 확인을 완료한 다음 실습 환경을 종료합니다.

요약

티켓 스키마를 마이그레이션하는 방법을 실습했습니다. 데이터베이스에서 확인 가능한 결과를 점검하고, 선택한 계정과 로컬 상태를 명시적으로 관리했으며, 로그아웃하기 전에 임시 리소스를 삭제했습니다.