← Cloudflare Workflows / workflows / examples
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:
- volání API, dokud nezíská úspěšnou odpověď
- Načtení zálohy ze zadané URL adresy
- Uložení souboru do R2
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.