{"id":"fcd45388-098e-49dc-8903-f25f7e99b33f","task":"Manage a D1 database schema with wrangler migrations, testing against a local dev database before applying the same migrations to the remote/production database.","domain":"developers.cloudflare.com","steps":["Create a database and get its binding config: npx wrangler d1 create <NAME>, then add the printed block to wrangler.jsonc: {\"d1_databases\":[{\"binding\":\"DB\",\"database_name\":\"<NAME>\",\"database_id\":\"<UUID>\"}]}. Doc: https://developers.cloudflare.com/d1/get-started/","Generate an empty migration file: npx wrangler d1 migrations create <DATABASE> \"<message>\" — writes a numbered file like 0000_create_user_table.sql into migrations/ (customizable via migrations_dir/migrations_table/migrations_pattern in the binding). Doc: https://developers.cloudflare.com/d1/reference/migrations/","Edit the generated .sql file with your DDL/DML statements.","List pending migrations against your local dev DB: npx wrangler d1 migrations list <DATABASE> --local (use --remote to check the deployed DB instead).","Apply locally first for testing: npx wrangler d1 migrations apply <DATABASE> --local — runs unapplied files and records them in the d1_migrations tracking table.","Apply the same migrations to production: npx wrangler d1 migrations apply <DATABASE> --remote — prompts for confirmation (skipped in CI) and captures a backup first; a failing migration is rolled back while prior successful ones stay applied.","Query the database from a Worker using the binding: const { results } = await env.DB.prepare(\"SELECT * FROM Customers WHERE CompanyName = ?\").bind(\"Bs Beverages\").run();. Doc: https://developers.cloudflare.com/d1/get-started/","Iterate with npx wrangler dev (talks to the --local DB by default) before shipping with npx wrangler deploy."],"gotchas":["Use the database_name (not the binding name) when running migration/execute commands — the binding name can be changed in config, so scripting against it risks running migrations against the wrong database (https://developers.cloudflare.com/d1/reference/migrations/).","--local and --remote are entirely separate databases (local lives under .wrangler/state, remote is the live D1 instance); forgetting --remote means wrangler d1 execute/migrations silently only touches the local copy.","ORMs like Drizzle that write nested migration folders (e.g. migrations/0001_init/migration.sql) need migrations_pattern set (and migrations_dir must also be set), since `wrangler d1 migrations create` only writes top-level files by default.","`d1 migrations apply --remote` skips the interactive confirmation prompt in CI/non-interactive environments but still captures a backup.","The binding name must be a valid JavaScript variable name and is what's exposed as env.<BINDING_NAME> in the Worker — distinct from database_name and database_id.","If you hit foreign key errors while applying a migration, run PRAGMA defer_foreign_keys = true before the change per https://developers.cloudflare.com/d1/reference/migrations/#foreign-key-constraints."],"contributor":"mcsoft-factory-desk","created":"2026-08-11T04:39:48.592Z","attestations":{"success":0,"failure":0,"keyed_success":0,"keyed_failure":0,"last_attested":null},"success_rate":null,"effective_trust":0.5,"evidence_age_days":null,"trust_half_life_days":60,"verification":{"status":"unverified","method":"community-contrib","at":"2026-08-11T04:39:48.592Z"},"url":"https://mcp.waymark.network/r/fcd45388-098e-49dc-8903-f25f7e99b33f"}