INTEGRITY Dokumentace

Export a uložení databáze D1

V tomto příkladu implementujeme Workflow, který se spouští podle plánu pomocí schedules pole ve vazbě Workflow. Tento Workflow zahájí zálohování databáze D1 pomocí REST API a poté uloží SQL výpis do R2 bucket.

Po spuštění Workflow zavolá REST API a zahájí exportní úlohu pro konkrétní databázi. Poté volá stejný koncový bod, aby zjistil, zda je záložní úloha hotová a zda je SQL dump k dispozici ke stažení.

Jak ukazuje tento příklad, Workflows zpracovává odpovědi i selhání, čímž vývojáře zbavuje této zátěže. Workflows opakuje následující kroky:

Workflow může běžet, dokud není záložní soubor připravený, a zvládá přitom všechny možné stavy až do dokončení.

Tento příklad ukazuje zjednodušené kroky pro zálohování D1 databázi, která vám pomůže pochopit možnosti Workflows. V každém kroku využívá výchozí konfiguraci uspávání a opakování. V reálném scénáři by pravděpodobně bylo potřeba více kroků a další logika.

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 });
	},
};

Zde je minimální package.json:

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

Vytvořit D1_REST_API_TOKEN jako secret s oprávněním exportovat cílovou databázi D1.

Zde je Konfigurační soubor Wrangler:

{
	"$schema": "./node_modules/wrangler/config-schema.json",
	"name": "backup-d1",
	"main": "src/index.ts",
	// Set this to today's date
	"compatibility_date": "2026-08-28",
	"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-08-28"
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"

Každé naplánované spuštění automaticky vytvoří novou instanci Workflow.

Naplánované instance obsahují odpovídající cron výraz a naplánovaný čas spuštění na event.schedule.

Při konfiguraci plánů Workflow používejte nejnovější verzi Wrangleru. Pokud vaše místní schéma Wrangleru nerozpoznává schedules ještě nemáte, před nasazením aktualizujte Wrangler.