Skip to content

[wrangler] Fix nested D1 migrations#13913

Open
swalker326 wants to merge 9 commits into
cloudflare:mainfrom
swalker326:d1-recursive-migrations-13257
Open

[wrangler] Fix nested D1 migrations#13913
swalker326 wants to merge 9 commits into
cloudflare:mainfrom
swalker326:d1-recursive-migrations-13257

Conversation

@swalker326

@swalker326 swalker326 commented May 13, 2026

Copy link
Copy Markdown

Fixes #13257.

Fix D1 migration discovery so wrangler d1 migrations list and wrangler d1 migrations apply recursively include nested .sql files under migrations_dir. Nested migrations are recorded using relative paths, and wrangler d1 migrations create now accounts for nested numeric prefixes when choosing the next migration number.


  • Tests
    • Tests included/updated
    • Automated tests not possible - manual testing has been completed as follows:
    • Additional testing not necessary because:
  • Public documentation
    • Cloudflare docs PR(s):
    • Documentation not necessary because: this fixes existing Wrangler D1 migration behavior without changing public command usage.

A picture of a cute animal (not mandatory, but encouraged)

30D310E7-7F82-47F2-8C87-86AB5CE8C22D_1_105_c
Open in Devin Review

@changeset-bot

changeset-bot Bot commented May 13, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 873f35c

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 3 packages
Name Type
wrangler Patch
@cloudflare/vite-plugin Patch
@cloudflare/vitest-pool-workers Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@workers-devprod workers-devprod requested review from a team and NuroDev and removed request for a team May 13, 2026 15:39
@workers-devprod

workers-devprod commented May 13, 2026

Copy link
Copy Markdown
Contributor

Codeowners approval required for this PR:

  • @cloudflare/d1
  • ✅ @cloudflare/wrangler
Show detailed file reviewers
  • packages/wrangler/src/tests/d1/migrate.test.ts: [@cloudflare/d1]
  • packages/wrangler/src/tests/d1/migrations/helpers.test.ts: [@cloudflare/d1]
  • packages/wrangler/src/d1/execute.ts: [@cloudflare/d1]
  • packages/wrangler/src/d1/migrations/apply.ts: [@cloudflare/d1]
  • packages/wrangler/src/d1/migrations/helpers.ts: [@cloudflare/d1]

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 6 additional findings.

Open in Devin Review

@NuroDev NuroDev left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great little fix. Thank you @swalker326!

@NuroDev NuroDev enabled auto-merge (squash) May 14, 2026 10:08
@github-project-automation github-project-automation Bot moved this to Untriaged in workers-sdk May 14, 2026
@pkg-pr-new

pkg-pr-new Bot commented May 14, 2026

Copy link
Copy Markdown
create-cloudflare

npm i https://pkg.pr.new/create-cloudflare@13913

@cloudflare/kv-asset-handler

npm i https://pkg.pr.new/@cloudflare/kv-asset-handler@13913

miniflare

npm i https://pkg.pr.new/miniflare@13913

@cloudflare/pages-shared

npm i https://pkg.pr.new/@cloudflare/pages-shared@13913

@cloudflare/unenv-preset

npm i https://pkg.pr.new/@cloudflare/unenv-preset@13913

@cloudflare/vite-plugin

npm i https://pkg.pr.new/@cloudflare/vite-plugin@13913

@cloudflare/vitest-pool-workers

npm i https://pkg.pr.new/@cloudflare/vitest-pool-workers@13913

@cloudflare/workers-editor-shared

npm i https://pkg.pr.new/@cloudflare/workers-editor-shared@13913

@cloudflare/workers-utils

npm i https://pkg.pr.new/@cloudflare/workers-utils@13913

wrangler

npm i https://pkg.pr.new/wrangler@13913

commit: 873f35c

Comment thread packages/wrangler/src/__tests__/d1/migrate.test.ts
@alsuren alsuren mentioned this pull request May 14, 2026
5 tasks
@k0d13

k0d13 commented May 14, 2026

Copy link
Copy Markdown

A little concerned that this may break existing flows
I use drizzle and just have a script that copies the drizzle/*/migration.sql, modifies it, and writes it to drizzle/*.sql
If nested support alone is added, how will it handle both the old drizzle/*.sql and the "new" drizzle/*/migration.sql?

[edited by alsuren to add backticks]

@swalker326

Copy link
Copy Markdown
Author

A little concerned that this may break existing flows I use drizzle and just have a script that copies the drizzle//migration.sql, modifies it, and writes it to drizzle/.sql If nested support alone is added, how will it handle both the old drizzle/.sql and the "new" drizzle//migration.sql?

Nested directories are not required, they're just supported with this PR. You can put top level *.sql files OR folders with *.sql files in them. For your setup you would see no change, continue to copy the sql files over.

auto-merge was automatically disabled May 15, 2026 22:53

Head branch was pushed to by a user without write access

@swalker326 swalker326 closed this May 16, 2026
@github-project-automation github-project-automation Bot moved this from Untriaged to Done in workers-sdk May 16, 2026
@swalker326 swalker326 reopened this May 16, 2026
@github-project-automation github-project-automation Bot moved this from Done to Untriaged in workers-sdk May 16, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A little concerned that this may break existing flows I use drizzle and just have a script that copies the drizzle/*/migration.sql, modifies it, and writes it to drizzle/*.sql If nested support alone is added, how will it handle both the old drizzle/*.sql and the "new" drizzle/*/migration.sql?

(switching to a comment on the diff so that we can have a threaded discussion instead of quote-replying)

I'm going to check in with the team about this one. I suppose what @k0d13 is asking for is to hide this behaviour change behind a --recursive flag or something. I think I would argue against doing that (thinking out loud):

1. I'm not expecting this to be very common

I would expect most people to make their "nested drizzle to d1" scripts write to a separate directory (a tempdir, or a separate local folder that's in .gitignore, and can be nuked at the start of the script). If it turns out that someone has posted a workaround script somewhere that encourages people to dump everything in the same dir, I might have to rethink this position.

2. Migrations should be idempotent or fail-fast

Since D1 only has up migrations (no down migrations), I would expect most people to either be writing idempotent migrations or having things fail early rather than corrupting data.

I have not checked whether drizzle does a good job of this in practice. If drizzle tends to write its migrations as create table ... (rather than the create table if not exists ... idempotent form) then the first migration will fail immediately and we will be safe.

It may be that there is some edge case where someone writes a set of step-by-step idempotent migrations that will cause data loss when re-applied from start to finish on top of a production database. In this edge case, the user will need to use time-travel to restore to the point before the migration. I would expect this to also cause problems against a local database though, which should make this more rare.

3. I would prefer to make things "just work" in the long term, or at least have a pit of success

If we decide to go with a --recursive feature flag as an interim measure, we should have some kind of "There are no top level migrations in $dir, but there are migrations in child folders. Pass --recursive to migrate these too" handling.

I would prefer to limit the complexity and say "we will always recursively apply sql migrations, and this is the search order"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once the D1 team have decided on the resolution, the workers-sdk team are happy to merge this.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After chatting about this internally, it seems like we're not happy to accept the risk of running people's destructive migrations when we didn't previously.

(for cloudflare internal people, there is a bit more discussion at https://wiki.cfdata.org/spaces/~ivory/pages/1406859534/Fix+Nested+D1+Migrations)

The proposal is that we should add a migrations_pattern config item in wrangler.jsonc .

(similar to how migrations_dir is specified in https://developers.cloudflare.com/d1/reference/migrations/#wrangler-customizations)

We will not allow it to be configured on the command-line for now.

There are a whole bunch of edge cases and "pit of success" considerations to think about. Its error messages also need to play well with claude.

  1. the default behaviour must not change (migrations_pattern should default to $migrations_dir/*.sql if not specified)
  2. if wrangler d1 migrations create tries to make a migration file that does not match the pattern, it should return an actionable error
  3. if there are no migrations matching the pattern, but there are some matching $migrations_dir/*/migration.sql, wrangler d1 migrations list and wrangler d1 migrations list should log a hint to stderr suggesting setting migrations_pattern to $migrations_dir/*/migration.sql (as a special case to help create a pit of success for drizzle specifically. We can expand this list of hint search patterns later, but let's start by being conservative for now)
  4. tests covering all of the edge cases and error flows
  5. We also need to update the documentation linked above.
  6. ... I feel like there is something else that I'm missing.

This is not a small change anymore. I will try to take it on myself next week.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

really appreciative of the conversation and looking forward to seeing this land.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Untriaged

Development

Successfully merging this pull request may close these issues.

D1 migrations_dir | Support recursive .sql file search

8 participants