소개
지원 팀은 티켓의 식별 정보를 잃지 않고 필터링하고 업데이트할 수 있는 기록이 필요합니다. Cloudflare D1은 관련 정보를 테이블에 저장하고, 원하는 데이터를 설명하는 언어인 SQL을 지원하는 관리형 데이터베이스입니다. 테이블은 스프레드시트와 비슷합니다. 각 행은 하나의 티켓이고, 이름이 지정된 열에는 티켓의 필드가 저장됩니다.
이 과정을 시작하기 전에 Connect LabEx to Your Cloudflare Account를 완료하세요. 이 실습에서는 LabEx VM 터미널, 디바이스 인증, 계정 확인, 실제 account ID 저장 방법을 다룹니다. 직접 입력하는 학습자는 먼저 해당 실습을 완료해야 합니다. 간단한 JavaScript Worker 도 이해하고 있어야 하지만, 여기서는 SQL 지식을 요구하지 않습니다.
이 실습에서는 데이터베이스를 만들고, 유효한 티켓을 위한 규칙을 정의하며, 로컬 실습 레코드와 클라우드 레코드를 구분합니다. 배포된 Worker 는 필요하지 않으며, 삭제할 임시 D1 데이터베이스 하나가 필요합니다.
자신의 학습 계정과 새 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 을 브라우저에서 열고 현재 코드를 입력한 다음, 학습 계정과 권한을 확인하고 인증을 승인하세요. 터미널에서 성공 메시지가 표시될 때까지 기다립니다. 비밀번호나 토큰을 프로젝트 파일에 붙여 넣지 마세요.

이 예시에는 계정 액세스 및 필요한 background access 와 함께 D1 Write 권한이 표시되어 있습니다. 인증하기 전에 직접 선택한 학습 계정이 맞는지 확인하세요.
npx wrangler whoami --json
loggedIn: true인지 확인한 다음, 계정이 하나만 표시되더라도 계정의 name과 id를 읽습니다. 사용할 ID 를 아래 설정에 복사합니다. 다음 셸 변수는 6 개의 무작위 바이트 (16 진수 12 자) 를 사용해 다른 학습자와 이름이 충돌하지 않도록 합니다. here-document 는 JSON 줄 사이의 JSON 을 작성하며, 그 안에서 $RUN이 확장됩니다.
$schema 앞의 백슬래시는 이 JSON 키를 그대로 유지하며, $RUN 은 이번 실행의 고유 이름으로 확장됩니다.
RUN=labex-c04-d01-$(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 변경 사항은 로컬에만 적용합니다.
삭제할 클라우드 데이터베이스를 만듭니다. --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 중 하나를 포함하세요.
CREATE TABLE은 테이블을 정의합니다. INTEGER PRIMARY KEY는 각 행에 고유한 숫자 식별자를 부여합니다. TEXT는 문자열을 저장합니다. NOT NULL은 값이 없는 것을 금지하고, CHECK는 규칙을 벗어난 값을 거부합니다. DEFAULT는 INSERT 에서 해당 필드를 생략했을 때 사용할 값을 제공합니다. 이러한 검사를 통해 불완전한 티켓을 방지할 수 있습니다.
스키마와 합성 레코드 두 개를 SQL 파일에 작성합니다. 따옴표로 묶은 SQL 표시는 셸이 파일 내용을 해석하지 않도록 합니다. SQL 문은 세미콜론으로 끝납니다. INSERT INTO는 열 이름과 각 행의 값을 대응시킵니다.
cat > schema.sql <<'SQL'
CREATE TABLE tickets (
id INTEGER PRIMARY KEY,
subject TEXT NOT NULL CHECK(length(trim(subject)) > 0),
status TEXT NOT NULL DEFAULT 'open' CHECK(status IN ('open','closed')),
source TEXT NOT NULL
);
INSERT INTO tickets (id, subject, status, source) VALUES
(1, 'Cannot sign in', 'open', 'seed'),
(2, 'Invoice copy', 'closed', 'seed');
SQL
파일을 로컬 데이터베이스에만 적용합니다.
npx wrangler d1 execute DB --local --file schema.sql
명령이 성공하면 로컬 데이터베이스에서 실행되었다는 메시지가 표시됩니다. 이 메시지만으로 원격 테이블이 존재한다고 판단할 수는 없습니다. SQLite 의 PRAGMA table_info를 사용해 열 정의를 확인합니다.
npx wrangler d1 execute DB --local --command "PRAGMA table_info(tickets);"
id, subject, status, source가 표시되어야 합니다. pk 필드는 기본 키를 나타내고, notnull은 필수 값을 기록합니다.
로컬 행 필터링, 업데이트 및 삭제하기
이 단계에서는 기본 SQL 을 연습하고 로컬 전용 표시를 남깁니다. SELECT는 열을 선택하고, FROM은 테이블을 지정하며, WHERE는 일치하는 행을 필터링하고, ORDER BY는 결과 순서를 예측 가능하게 만듭니다.
npx wrangler d1 execute DB --local --command "SELECT id, subject FROM tickets WHERE status = 'open' ORDER BY id;"
결과에는 티켓 1 과 Cannot sign in이 표시되어야 합니다. SQL 문자열은 명령 전체를 감싼 큰따옴표 안에서 작은따옴표를 사용합니다. 로컬 실습 티켓을 추가합니다.
npx wrangler d1 execute DB --local --command "INSERT INTO tickets (id, subject, source) VALUES (3, 'Local rehearsal', 'local');"
UPDATE는 조건에 맞는 행을 변경합니다. 실행하기 전에 항상 WHERE 조건을 확인하세요. WHERE를 생략하면 모든 행이 변경됩니다.
npx wrangler d1 execute DB --local --command "UPDATE tickets SET status = 'closed' WHERE id = 3;"
잘못된 상태 값을 사용해 제약 조건이 데이터를 보호하는지 확인합니다.
npx wrangler d1 execute DB --local --command "UPDATE tickets SET status = 'lost' WHERE id = 3;"
이 명령은 의도적으로 실패해야 합니다. 인증 오류나 네트워크 오류가 아니라 CHECK constraint failed 메시지가 표시되어야 합니다. 해당 행은 closed 상태로 남아 있어야 합니다. 임시 행 하나를 만든 다음 삭제합니다. DELETE는 조건에 일치하는 행만 제거합니다.
npx wrangler d1 execute DB --local --command "INSERT INTO tickets (id, subject, source) VALUES (4, 'Temporary', 'local'); DELETE FROM tickets WHERE id = 4;"
남은 행을 확인합니다.
npx wrangler d1 execute DB --local --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
ID 1, 2, 3 이 표시되어야 합니다. 티켓 3 은 closed 상태이고 source 는 local이어야 합니다. 티켓 4 는 없어야 합니다. 실패한 업데이트가 유효한 행을 변경하지 않았는지도 확인하세요.
원격 데이터베이스에 초기 데이터 입력 및 확인하기
이 단계에서는 동일한 스키마를 클라우드 데이터베이스에 적용하고, 로컬 변경 사항이 자동으로 원격 데이터베이스에 반영되지 않았음을 확인합니다. --remote는 선택한 계정의 데이터베이스 UUID 에 SQL 문을 전송합니다.
npx wrangler d1 execute DB --remote --file schema.sql
확인 메시지가 표시되면 이 실습에서 만든 데이터베이스만 승인하세요. 로컬 실습 행과 같은 ID 를 사용하지만 다른 데이터를 가진 원격 전용 행을 추가합니다.
npx wrangler d1 execute DB --remote --command "INSERT INTO tickets (id, subject, source) VALUES (3, 'Cloud inbox', 'remote');"
두 대상의 데이터를 명시적으로 확인합니다.
npx wrangler d1 execute DB --remote --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
npx wrangler d1 execute DB --local --command "SELECT id, subject, status, source FROM tickets ORDER BY id;"
원격 티켓 3 은 Cloud inbox, open, remote로 표시되고, 로컬 티켓 3 은 Local rehearsal, closed, local로 남아 있어야 합니다. 이 차이는 올바른 대상을 선택했다는 증거입니다.
Cloudflare Dashboard 에서 동일한 계정을 선택하고 Storage & databases → D1 SQLite Database를 엽니다. 이번 실행에서 만든 정확한 데이터베이스 이름을 찾아 세부 정보 페이지를 엽니다. 데이터베이스 ID 가 wrangler.jsonc의 ID 와 일치하는지 비교합니다. 읽기 전용 테이블 보기를 사용할 수 있다면 이를 사용해 tickets를 확인하세요. 해당 화면에서 레코드를 만들거나 수정하지 마세요. 행의 내용은 위 SQL 응답으로 확인할 수 있으며, Metrics 의 지연된 수치는 확인 근거가 아닙니다.
데이터베이스를 삭제하기 전에 이 단계의 검증을 실행하세요.

Explore Data 를 열고 Studio 에서 tickets 를 선택합니다. 행을 편집하지 않고 확인하세요. 예시의 임의 데이터베이스 이름은 한 번의 테스트 실행에 해당하며 자신의 이름과는 다릅니다. 티켓 3 은 Cloud inbox, source 는 remote 이지만 로컬 데이터베이스에는 여전히 Local rehearsal, source 가 local 인 행이 있습니다.
임시 리소스 삭제하기
이 단계에서는 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 이 아닐 수 있습니다. 구조화된 응답에 명시적으로 로그아웃 상태가 표시된 경우에만 이는 정상입니다. 검증을 완료한 다음 실습 환경을 종료하세요.
요약
지원 티켓 데이터베이스를 만드는 방법을 연습했습니다. 확인 가능한 데이터베이스 결과를 점검하고, 선택한 계정과 로컬 상태를 명확히 구분했으며, 로그아웃하기 전에 임시 리소스를 삭제했습니다.



