D1 では、既存の SQLite テーブルとそのデータを直接インポートできます。既存データをすばやく D1 へ移行できます。Workers と D1 を使うようにアプリケーションを移行する場合や、スキーマをローカルで試作してから D1 データベースへ取り込む場合に便利です。
D1 ではデータベースのエクスポートもできます。ローカル開発 やテストに使えます。
既存の SQLite データベースを D1 にインポートするには、次が必要です。
- インストール済みの Cloudflare Wrangler CLI。
- 取り込み先として使うデータベース。
- インポートする既存の SQLite(バージョン 3.0 以降)データベースファイル。
たとえば、次の users_export.sql はスキーマと値を含み、CREATE TABLE IF NOT EXISTS 文があります。
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テーブルが正しくインポートされ、クエリできることを確認するには、SELECT 文を実行して D1 データベースの全テーブルを取得します。
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 │
└────────┘ここから、新しいテーブルを Worker から D1 Workers Binding API でクエリできます。
別システムにある既存の 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 の入力として使い、既存データベースのインポート の手順に進みます。
既存の 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.sqlD1 データベースのスキーマだけをエクスポートするには:
npx wrangler d1 export <database_name> --remote --output=./schema.sql --no-dataD1 テーブルのスキーマだけをエクスポートするには:
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./schema.sql --no-dataD1 データベースのデータだけをエクスポートするには:
npx wrangler d1 export <database_name> --remote --output=./data.sql --no-schemaD1 テーブルのデータだけをエクスポートするには:
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./data.sql --no-schema- 仮想テーブル、および仮想テーブルを含むデータベースのエクスポートはサポートされません。D1 は SQLite の FTS5 モジュール ↗ による全文検索向けに仮想テーブルをサポートします。回避策として、仮想テーブルを削除してからエクスポートし、その後に仮想テーブルを再作成します。
- 実行中のエクスポートは、ほかのデータベースリクエストをブロックします。
- 列の数値は、JavaScript の数値の 52 ビット精度の影響を受けます。非常に大きな数(
int64)を保存して同じ値を取得すると、元の数より精度が落ちる場合があります。
既存のスキーマやデータセットを D1 にインポートしようとしてエラーになる場合:
- データが SQL 形式(通常は
.sql拡張子)であることを確認します。.sqlite3のデータベースダンプがある場合は、SQLite ファイルの変換方法 を参照してください。 - スキーマが SQLite3 ↗ と互換であることを確認します。型と SQL 構文が直接互換ではないため、MySQL や PostgreSQL のデータベースから D1 へデータをインポートすることはできません。
- テーブル間に外部キー関係がある場合は、正しい順序でテーブルをインポートします。まだ存在しないテーブルは参照できません。
"cannot start a transaction within a transaction"エラーが出る場合は、ダンプした SQL 文からBEGIN TRANSACTIONとCOMMITを削除したことを確認します。
大きな SQL ファイルを D1 にインポートしようとして Statement too long エラーになる場合、ファイル内のいずれかの SQL 文が最大長を超えています。
この問題を解消するには、1 つの大きな INSERT 文を、複数の小さな INSERT 文に分割します。たとえば、1,000 行を 1 文で挿入する代わりに、次のコードのように 250 行ずつの 4 グループに分けます。
変更前:
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');変更後:
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');データをインポートするとき、外部キー制約 を一時的に無効にする必要がある場合があります。外部キーに違反する変更をする前に、PRAGMA defer_foreign_keys = true を呼び出します。
外部キーと D1 の扱いについては、外部キーのドキュメント を参照してください。
- SQLite の
CREATE TABLE↗ ドキュメントを読む。 - Worker 内から D1 Workers Binding API の使い方 を学ぶ。
- D1 での データベースマイグレーションの仕組み を理解する。