コンテンツにスキップ

データのインポートとエクスポート

D1では、既存のSQLiteテーブルとそのデータを直接インポートできるため、既存のデータを迅速かつ簡単にD1に移行できます。これは、アプリケーションをWorkersとD1に移行する際や、D1データベースにインポートする前にローカルでスキーマをプロトタイプしたい場合に便利です。

D1では、データベースをエクスポートすることもできます。これは、ローカル開発やテストに役立ちます。

既存のデータベースをインポートする

既存のSQLiteデータベースをD1にインポートするには、次の条件を満たす必要があります。

  1. CloudflareのWrangler CLIがインストールされていること。
  2. ターゲットとして使用するデータベースがあること。
  3. インポートするための既存の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フラグを渡して、テーブルスキーマと値を実行(インポート)できます。

Terminal window
npx wrangler d1 execute example-db --remote --file=users_export.sql

テーブルが正しくインポートされ、クエリ可能であることを確認するために、D1データベースからすべてのテーブルを取得するSELECTステートメントを実行します。

Terminal window
npx wrangler d1 execute example-db --remote --command "SELECT name FROM sqlite_schema WHERE type='table' ORDER BY name;"
...
🌀 ローカル開発データベースで実行するには、wranglerコマンドから--remoteフラグを削除してください。
🚣 0.3165msで1つのコマンドを実行しました
┌────────┐
name
├────────┤
_cf_KV
├────────┤
users
└────────┘

ここから、D1クライアントAPIを使用してWorkerから新しいテーブルをクエリできます。D1クライアントAPIを使用します。

SQLiteデータベースファイルの変換

他のシステムから既存のSQLiteデータベースがある場合、そのテーブルをD1データベースにインポートできます。sqliteコマンドラインツールを使用して、.sqlite3ファイルをD1データベースに対してインポート(実行)できる一連のSQLステートメントに変換できます。

例えば、db_dump.sqlite3という生のSQLiteダンプがある場合、次のsqliteコマンドを実行して変換します。

Terminal window
sqlite3 db_dump.sqlite3 .dump > db.sql

上記のコマンドを実行したら、出力されたSQLファイルをD1と互換性のある形式に編集する必要があります。

  1. ファイルからBEGIN TRANSACTIONCOMMIT;を削除します。
  2. 次のテーブル作成ステートメント(存在する場合)を削除します:
    CREATE TABLE _cf_KV (
    key TEXT PRIMARY KEY,
    value BLOB
    ) WITHOUT ROWID;

その後、生成した.sqlファイルを入力として使用して、既存のデータベースをインポートする手順に従うことができます。

外部キー制約

データをインポートする際、外部キー制約を一時的に無効にする必要がある場合があります。そのためには、外部キーを違反する変更を行う前にPRAGMA defer_foreign_keys = trueを呼び出します。

外部キーとD1の取り扱いについて詳しくは、外部キーのドキュメントを参照してください。

既存のD1データベースをエクスポートする

既存のSQLiteデータベースをインポートするだけでなく、ローカル開発やテストのためにD1データベースをエクスポートしたい場合もあります。D1データベースを.sqlファイルにエクスポートするには、wrangler d1 exportを使用し、その後d1 execute --fileで実行(インポート)します。

D1データベースのスキーマとデータを完全にエクスポートするには:

Terminal window
npx wrangler d1 export <database_name> --remote --output=./database.sql

単一のテーブルのスキーマとデータをエクスポートするには:

Terminal window
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./table.sql

D1データベースのスキーマのみをエクスポートするには:

Terminal window
npx wrangler d1 export <database_name> --remote --output=./schema.sql --no-data

D1テーブルのスキーマのみをエクスポートするには:

Terminal window
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./schema.sql --no-data

D1データベースのデータのみをエクスポートするには:

Terminal window
npx wrangler d1 export <database_name> --remote --output=./data.sql --no-schema

D1テーブルのデータのみをエクスポートするには:

Terminal window
npx wrangler d1 export <database_name> --remote --table=<table_name> --output=./data.sql --no-schema

既知の制限

  • エクスポートは、仮想テーブルを含むデータベースには対応していません。D1はSQLiteのFTS5モジュールを使用してフルテキスト検索のための仮想テーブルをサポートしています。回避策として、仮想テーブルを削除してエクスポートし、その後仮想テーブルを再作成します。
  • 実行中のエクスポートは、他のデータベースリクエストをブロックします。

トラブルシューティング

既存のスキーマやデータセットをD1にインポートしようとしたときにエラーが発生した場合:

  • SQL形式(通常は.sqlファイル拡張子)でデータをインポートしていることを確認してください。.sqlite3データベースダンプがある場合は、SQLiteファイルを変換する方法を参照してください。
  • スキーマがSQLite3と互換性があることを確認してください。MySQLやPostgreSQLデータベースからD1にデータをインポートすることはできません。なぜなら、型やSQL構文が直接互換性がないからです。
  • テーブル間に外部キー関係がある場合、正しい順序でテーブルをインポートしていることを確認してください。まだ存在しないテーブルを参照することはできません。
  • "cannot start a transaction within a transaction"エラーが発生した場合、ダンプされたSQLステートメントからBEGIN TRANSACTIONCOMMITを削除したことを確認してください。

次のステップ