본문으로 바로가기 본문 바로가기
WIKI 기술 지식 베이스

데이터 가져오기와 내보내기 (Import and export data)

원문 보기 위키 갱신

D1을 사용하면 기존 SQLite 테이블과 그 데이터를 직접 가져올 수 있어서, 기존 데이터를 D1로 빠르고 쉽게 마이그레이션할 수 있어요. 이 기능은 애플리케이션을 Workers와 D1을 사용하도록 마이그레이션할 때, 또는 스키마를 D1 데이터베이스(들)로 가져오기 전에 로컬에서 프로토타이핑하고 싶을 때 유용해요.

D1은 또한 데이터베이스를 내보낼 수도 있어요. 이는 로컬 개발이나 테스트에 유용해요.

출처: 문서

본문

기존 데이터베이스 가져오기

기존 SQLite 데이터베이스를 D1로 가져오려면 다음이 있어야 해요.

  1. Cloudflare Wrangler CLI가 설치되어 있어야 해요.
  2. 대상으로 사용할 데이터베이스가 있어야 해요.
  3. 가져올 기존 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과 호환되도록 편집해야 해요.

  1. 파일에서 BEGIN TRANSACTION과 COMMIT;를 제거하세요.

  2. 다음 테이블 생성 구문이 있다면 제거하세요.

    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)

더 알아보기 (Learn more)