Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

D1 データベースをエクスポートして保存する

Workflows で D1 データベースを R2 ストレージへエクスポートします

最終更新 Markdown で表示Agent セットアップ

この例では、Workflow バインディングの schedules フィールドでスケジュール実行する Workflow を実装します。この Workflow は REST API で D1 データベースのバックアップを開始し、SQL ダンプを R2 バケットに保存します。

Workflow が起動されると、特定のデータベースのエクスポートジョブを開始するために REST API を呼び出します。そのあと、同じエンドポイントを呼び出して、バックアップジョブの準備ができているか、SQL ダンプをダウンロードできるかを確認します。

この例のとおり、Workflows はレスポンスと失敗の両方を処理するため、開発者の負担が減ります。Workflows は次のステップをリトライします。

  • 成功レスポンスが返るまでの API 呼び出し
  • 提供された URL からのバックアップ取得
  • ファイルの R2 への保存

バックアップファイルの準備ができるまで Workflow を実行でき、完了までのさまざまな条件を処理します。

この例は、Workflows でできることを理解しやすいように、D1 データベースをバックアップする手順を簡略化しています。各ステップでは、スリープとリトライの デフォルト 設定を使います。実際の運用では、さらに多くのステップと追加のロジックが必要になることがほとんどです。

import {
	WorkflowEntrypoint,
	WorkflowStep,
	WorkflowEvent,
} from "cloudflare:workers";

// We are using R2 to store the D1 backup
type Env = {
	BACKUP_WORKFLOW: Workflow;
	D1_REST_API_TOKEN: string;
	BACKUP_BUCKET: R2Bucket;
	ACCOUNT_ID: string;
	DATABASE_ID: string;
};

// Workflow logic
export class backupWorkflow extends WorkflowEntrypoint<Env> {
	async run(_event: WorkflowEvent<unknown>, step: WorkflowStep) {
		const accountId = this.env.ACCOUNT_ID;
		const databaseId = this.env.DATABASE_ID;

		const url = `https://api.cloudflare.com/client/v4/accounts/${accountId}/d1/database/${databaseId}/export`;
		const method = "POST";
		const headers = new Headers();
		headers.append("Content-Type", "application/json");
		headers.append("Authorization", `Bearer ${this.env.D1_REST_API_TOKEN}`);

		const bookmark = await step.do(
			`Starting backup for ${databaseId}`,
			async () => {
				const payload = { output_format: "polling" };

				const res = await fetch(url, {
					method,
					headers,
					body: JSON.stringify(payload),
				});
				const { result } = (await res.json()) as any;

				// If we don't get `at_bookmark` we throw to retry the step
				if (!result?.at_bookmark) throw new Error("Missing `at_bookmark`");

				return result.at_bookmark;
			},
		);

		await step.do("Check backup status and store it on R2", async () => {
			const payload = { current_bookmark: bookmark };

			const res = await fetch(url, {
				method,
				headers,
				body: JSON.stringify(payload),
			});
			const { result } = (await res.json()) as any;

			// The endpoint sends `signed_url` when the backup is ready to download.
			// If we don't get `signed_url` we throw to retry the step.
			if (!result?.signed_url) throw new Error("Missing `signed_url`");

			const dumpResponse = await fetch(result.signed_url);
			if (!dumpResponse.ok) throw new Error("Failed to fetch dump file");

			// Finally, stream the file directly to R2
			await this.env.BACKUP_BUCKET.put(result.filename, dumpResponse.body);
		});
	}
}

export default {
	async fetch(req: Request, env: Env): Promise<Response> {
		return new Response("Not found", { status: 404 });
	},
};

最小構成の package.json は次のとおりです。

{
	"devDependencies": {
		"wrangler": "^3.99.0"
	}
}

対象の D1 データベースをエクスポートできる権限で、D1_REST_API_TOKENシークレット として作成します。

Wrangler 設定ファイル は次のとおりです。

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "backup-d1",
	"main": "src/index.ts",
	// Set this to today's date
	"compatibility_date": "2026-09-20",
	"compatibility_flags": [
		"nodejs_compat"
	],
	"vars": {
		"ACCOUNT_ID": "account-id",
		"DATABASE_ID": "database-id"
	},
	"workflows": [
		{
			"name": "backup-workflow",
			"binding": "BACKUP_WORKFLOW",
			"class_name": "backupWorkflow",
			"schedules": ["0 0 * * *"]
		}
	],
	"r2_buckets": [
		{
			"binding": "BACKUP_BUCKET",
			"bucket_name": "d1-backups"
		}
	]
}
"$schema" = "./node_modules/wrangler/config-schema.json"
name = "backup-d1"
main = "src/index.ts"
# Set this to today's date
compatibility_date = "2026-09-20"
compatibility_flags = [ "nodejs_compat" ]

[vars]
ACCOUNT_ID = "account-id"
DATABASE_ID = "database-id"

[[workflows]]
name = "backup-workflow"
binding = "BACKUP_WORKFLOW"
class_name = "backupWorkflow"
schedules = [ "0 0 * * *" ]

[[r2_buckets]]
binding = "BACKUP_BUCKET"
bucket_name = "d1-backups"

スケジュール実行のたびに、新しい Workflow インスタンスが自動で作成されます。

スケジュールされたインスタンスには、一致した cron 式と、スケジュールされた起動時刻が event.schedule に含まれます。

Workflow のスケジュールを設定するときは、最新の Wrangler を使います。ローカルの Wrangler スキーマがまだ schedules を認識しない場合は、デプロイ前に Wrangler を更新します。

役に立ちましたか?