데이터 가져오기와 내보내기 (Import and export data)
D1을 사용하면 기존 SQLite 테이블과 그 데이터를 직접 가져올 수 있어서, 기존 데이터를 D1로 빠르고 쉽게 마이그레이션할 수 있어요. 이 기능은 애플리케이션을 Workers와 D1을 사용하도록 마이그레이션할 때, 또는 스키마를 D1 데이터베이스(들)로 가져오기 전에 로컬에서 프로토타이핑하고 싶을 때 유용해요.
D1은 또한 데이터베이스를 내보낼 수도 있어요. 이는 로컬 개발이나 테스트에 유용해요.
출처: 문서
본문
기존 데이터베이스 가져오기
기존 SQLite 데이터베이스를 D1로 가져오려면 다음이 있어야 해요.
- Cloudflare Wrangler CLI가 설치되어 있어야 해요.
- 대상으로 사용할 데이터베이스가 있어야 해요.
- 가져올 기존 SQLite(버전 3.0+) 데이터베이스 파일이 있어야 해요.
참고
원시 SQLite 데이터베이스(.sqlite3 파일)는 직접 가져올 수 없어요. 먼저 기존 SQLite 파일을 변환하는 방법을 참고하세요.
예를 들어 CREATE TABLE IF NOT EXISTS 구문을 포함하는 다음과 같은 users_export.sql 스키마와 값을 생각해 보세요.
CREATE TABLE IF NOT EXISTS users (
id VARCHAR(50),
full_name VARCHAR(50),
created_on DATE
);
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCN9519NRVXWTPG0V0BF', 'Catlaina Harbar', '2022-08-20 05:39:52');
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCNBYBGX2GC6ZGY9FMP4', 'Hube Bilverstone', '2022-12-15 21:56:13');
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCNCWAJWRQWC2863MYW4', 'Christin Moss', '2022-07-28 04:13:37');
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCNDGQNBQAJG1AP0TYXZ', 'Vlad Koche', '2022-11-29 17:40:57');
INSERT INTO users (id, full_name, created_on) VALUES ('01GREFXCNF67KV7FPPSEJVJMEW', 'Riane Zamora', '2022-12-24 06:49:04');
현재 작업 디렉터리에 users_export.sql 파일이 있다면, d1 execute에 --file=users_export.sql 플래그를 전달해서 테이블 스키마와 값을 실행(가져오기)할 수 있어요.
npx wrangler d1 execute example-db --remote --file=users_export.sql
테이블이 올바르게 가져와졌고 쿼리 가능한지 확인하려면 D1 데이터베이스에서 모든 테이블을 가져오는 SELECT 구문을 실행하세요.
npx wrangler d1 execute example-db --remote --command "SELECT name FROM sqlite_schema WHERE type='table' ORDER BY name;"
...
🌀 To execute on your local development database, remove the --remote flag from your wrangler command.
🚣 Executed 1 commands in 0.3165ms
┌────────┐
│ name │
├────────┤
│ _cf_KV │
├────────┤
│ users │
└────────┘
참고
_cf_KV 테이블은 D1의 기본 저장 시스템이 사용하는 예약 테이블이에요. 이 테이블은 쿼리할 수 없으며 계정에 읽기/쓰기 작업 요금을 발생시키지 않아요.
이제부터 D1 Workers Binding API를 사용해 Worker에서 새 테이블을 쿼리할 수 있어요.
알려진 제한 사항 (Known limitations)
가져오기의 경우 wrangler d1 execute --file은 R2 업로드 한도와 마찬가지로 5GiB 파일로 제한돼요. 5GiB보다 큰 가져오기에는 데이터를 여러 파일로 나누는 것을 권장해요.
SQLite 데이터베이스 파일 변환하기
참고
원시 SQLite3 데이터베이스 덤프(.sqlite3 파일)를 변환하려면 시스템에 sqlite 명령줄 도구 ↗︎가 설치되어 있어야 해요.
다른 시스템의 기존 SQLite 데이터베이스가 있다면 그 테이블을 D1 데이터베이스로 가져올 수 있어요. sqlite 명령줄 도구를 사용하면 .sqlite3 파일을 D1 데이터베이스에 대해 가져오기(실행)할 수 있는 일련의 SQL 구문으로 변환할 수 있어요.
예를 들어 db_dump.sqlite3이라는 원시 SQLite 덤프가 있다면, 다음 sqlite 명령으로 변환할 수 있어요.
sqlite3 db_dump.sqlite3 .dump > db.sql
위 명령을 실행한 다음에는 출력된 SQL 파일을 D1과 호환되도록 편집해야 해요.
-
파일에서
BEGIN TRANSACTION과COMMIT;를 제거하세요. -
다음 테이블 생성 구문이 있다면 제거하세요.
CREATE TABLE _cf_KV ( key TEXT PRIMARY KEY, value BLOB ) WITHOUT ROWID;
그런 다음 데이터베이스 덤프에서 생성한 .sql 파일을 wrangler d1 execute의 입력으로 사용해서 기존 데이터베이스 가져오기 단계를 따르면 D1로 가져올 수 있어요.
기존 D1 데이터베이스 내보내기
기존 SQLite 데이터베이스를 가져오는 것 외에, 로컬 개발이나 테스트를 위해 D1 데이터베이스를 내보내고 싶을 수도 있어요. wrangler d1 export를 사용해 D1 데이터베이스를 .sql 파일로 내보낸 다음 d1 execute --file로 실행(가져오기)할 수 있어요.
전체 D1 데이터베이스 스키마와 데이터를 내보내려면:
npx wrangler d1 export <database_name> --remote --output=./database.sql
단일 테이블 스키마와 데이터를 내보내려면:
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./table.sql
D1 데이터베이스 스키마만 내보내려면:
npx wrangler d1 export <database_name> --remote --output=./schema.sql --no-data
D1 테이블 스키마만 내보내려면:
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./schema.sql --no-data
D1 데이터베이스 데이터만 내보내려면:
npx wrangler d1 export <database_name> --remote --output=./data.sql --no-schema
D1 테이블 데이터만 내보내려면:
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./data.sql --no-schema
알려진 제한 사항 (Known limitations)
- 가상 테이블(virtual tables)을 포함한 데이터베이스는 물론 가상 테이블 자체도 내보내기가 지원되지 않아요. D1은 SQLite의 FTS5 모듈 ↗︎을 사용한 전문 검색(full-text search)을 위해 가상 테이블을 지원해요. 해결 방법으로 가상 테이블을 삭제하고, 내보낸 다음, 가상 테이블을 다시 만들면 돼요.
- 실행 중인 내보내기는 다른 데이터베이스 요청을 차단해요.
- 열의 숫자 값은 JavaScript의 숫자 52비트 정밀도의 영향을 받아요. 매우 큰 숫자(
int64)를 저장한 다음 같은 값을 검색하면, 반환되는 값이 원래 숫자보다 정밀도가 낮을 수 있어요.
문제 해결 (Troubleshooting)
기존 스키마 및/또는 데이터셋을 D1로 가져오려고 할 때 오류가 발생한다면:
- 데이터를 SQL 형식(일반적으로
.sql파일 확장자)으로 가져오는지 확인하세요..sqlite3데이터베이스 덤프가 있다면 SQLite 파일 변환 방법을 참고하세요. - 스키마가 SQLite3 ↗︎과 호환되는지 확인하세요. 타입과 SQL 구문이 직접 호환되지 않으므로 MySQL이나 PostgreSQL 데이터베이스의 데이터는 D1로 가져올 수 없어요.
- 테이블 사이에 외래 키 관계가 있다면 테이블을 올바른 순서로 가져오는지 확인하세요. 아직 존재하지 않는 테이블을 참조할 수는 없어요.
"cannot start a transaction within a transaction"오류가 발생한다면, 덤프된 SQL 구문에서BEGIN TRANSACTION과COMMIT를 제거했는지 확인하세요.
Statement too long 오류 해결하기
큰 SQL 파일을 D1로 가져오려고 할 때 Statement too long 오류가 발생한다면, 파일 안의 SQL 구문 중 하나가 최대 허용 길이를 초과한다는 뜻이에요.
이 문제를 해결하려면 단일 대형 INSERT 구문을 여러 개의 더 작은 INSERT 구문으로 변환하세요. 예를 들어 한 구문에서 1,000개 행을 삽입하는 대신, 아래 코드에 나와 있듯이 250개 행 단위의 네 그룹으로 나누세요.
이전 (Before):
INSERT INTO users (id, full_name, created_on)
VALUES
('1', 'Jacquelin Elara', '2022-08-20 05:39:52'),
('2', 'Hubert Simmons', '2022-12-15 21:56:13'),
...
('1000', 'Boris Pewter', '2022-12-24 07:59:54');
이후 (After):
INSERT INTO users (id, full_name, created_on)
VALUES
('1', 'Jacquelin Elara', '2022-08-20 05:39:52'),
...
('100', 'Eddy Orelo', '2022-12-15 22:16:15');
...
INSERT INTO users (id, full_name, created_on)
VALUES
('901', 'Roran Eroi', '2022-08-20 05:39:52'),
...
('1000', 'Boris Pewter', '2022-12-15 22:16:15');
외래 키 제약 조건 (Foreign key constraints)
데이터를 가져올 때 외래 키 제약 조건을 일시적으로 비활성화해야 할 수도 있어요. 그러려면 외래 키를 위반하는 변경을 하기 전에 PRAGMA defer_foreign_keys = true를 호출하세요.
외래 키와 D1을 다루는 방법을 더 배우려면 외래 키 문서를 참고하세요.
다음 단계 (Next Steps)
- SQLite
CREATE TABLE↗︎ 문서를 읽어 보세요. - Worker 안에서 D1 Workers Binding API를 사용하는 방법을 배워 보세요.
- 데이터베이스 마이그레이션이 D1과 어떻게 동작하는지 이해해 보세요.