Skip to content

Instantly share code, notes, and snippets.

@varna
Last active April 12, 2024 14:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save varna/07334fac76e4479a2fc950051131a34c to your computer and use it in GitHub Desktop.
Save varna/07334fac76e4479a2fc950051131a34c to your computer and use it in GitHub Desktop.
Idea on making Cloudflare wrangler CLI for D1 migrations better experience.

Wrangler D1 Migrations

Currently, D1 migrations are a bit yucky, because of:

  • scary defaults
  • not knowing on which db it is being ran
  • package.json scripts bloat

Scary defaults

EDIT: This happended on wrangler@3.48.0. This behaviour is gone on 3.50.0.

list runs on local by default, cause wrangler d1 migrations list db_name is the same as running wrangler d1 migrations list db_name --local.

apply runs on remote by default, cause wrangler d1 migrations apply db_name is the same as running wrangler d1 migrations apply db_name --remote.

Some silly me might run list first, and assume that apply works the same`. Oops!

Not knowing on which db migration command is being ran

Currently, when you run a command, it only prints the migration name. DB name is not being mentioned. Remote vs local not being mentioned. Nothing! It's scary. What if my friend came by and ran a pkg script with preset inputs without knowing more!

package.json scripts bloat

{
	"name": "name",
	"version": "1.0.0",
	"scripts": {
		"dev": "next dev --turbo --port 9001",
		"build": "next build",
		"start": "next start",
		"lint": "next lint",
		"pages:build": "npx @cloudflare/next-on-pages",
		"preview": "npm run pages:build && wrangler pages dev .vercel/output/static",
		"deploy": "npm run pages:build && wrangler pages deploy .vercel/output/static",
		"build-cf-types": "wrangler types --env-interface CloudflareEnv env.d.ts",
		"db:migration:create": "drizzle-kit generate:sqlite",
		"db:migration:list": "wrangler d1 migrations list db_name --local",
		"db:migration:apply": "wrangler d1 migrations apply db_name --local",
		"db:migration:list:prod": "wrangler d1 migrations list db_name --remote",
		"db:migration:apply:prod": "wrangler d1 migrations apply db_name --remote",
		"drizzle:patch": "drizzle-kit up:sqlite"
	}
}

And you still might need some README.md to explain more on this. Wouldn't it be nice to just run db:migration and then just pick what you need? Docs on the go in CLI!

This is current experience

wrangler d1 migrations:

✘ [ERROR] Not enough non-option arguments: got 0, need at least 1


wrangler d1 migrations

Interact with D1 Migrations

Commands:
  wrangler d1 migrations list <database>              List your D1 migrations
  wrangler d1 migrations create <database> <message>  Create a new Migration
  wrangler d1 migrations apply <database>             Apply D1 Migrations

Flags:
  -j, --experimental-json-config  Experimental: Support wrangler.json  [boolean]
  -c, --config                    Path to .toml configuration file  [string]
  -e, --env                       Environment to use for operations and .env files  [string]
  -h, --help                      Show help  [boolean]
  -v, --version                   Show version number  [boolean]
🪵  Logs were written to ...

I suggest making CLI experience smth more like this

wrangler d1 migrations:

On which database you would like to run a migration? (Options taken from wrangler.toml, more info at https://docs.etc.etc, you can also manually provide it with `wrangler d1 migrations db_name`)
 [ ] db_name ()
 [ ] Or create a new db now (`wrangler d1 create db_name`)

Select one choice and continue.

What would you like to do with D1 Migrations? (You can use flags to skip this step)
 [ ] List your D1 migrations (--list)
 [ ] Create a new Migration (--create)
 [ ] Apply D1 Migrations (--apply)

Select one choice and continue.

Where would you like to apply this command? (You can use flags to skip this step)
 [ ] Execute on your locally persisted D1 database. (--local)
 [ ] Execute on your remote D1 database. (--remote)
 [ ] Execute on your preview D1 database (as defined by preview_database_id in wrangler.toml). (--preview)

brr brr, migration does its thing

@varna
Copy link
Author

varna commented Apr 12, 2024

EDIT on Scary defaults:
This happended on wrangler@3.48.0. This behaviour is gone on 3.50.0.

@varna
Copy link
Author

varna commented Apr 12, 2024

So, I have an idea, what about making a CLI tool (maybe call it d1zard). It would use underlying CLI tools like wrangler d1. It would be an experiment, to push UX to the limits. If it works out, it could be merged back intro wrangler.

d1zard pretty much shows you the current state of your D1s in you project, and gives you options to work with it.

  • You can run it simply by pnpx d1zard without installing
  • It uses your wrangler.toml, or recommends you to use it instead of passing parameters via CLI
  • it updates env.d.ts for you too if CloudflareEnv present in env.d.ts
  • It lists currently bound D1s and lets you to bind or create a new one
    • it has the ability, to list D1s from your CF Account
  • Changes are saved back to wrangler.toml
  • (optional nice to have) It could have support for drizzle/prisma too, which would replace wrangler d1 migrations create with drizzle-kit generate:sqlite or prisma counterpart. Or maybe even create default file like this:
// Path: drizzle.config.ts
import { defineConfig } from "drizzle-kit"

export default defineConfig({
  schema: "./drizzle/schema.ts",
  out: "./migrations",
  driver: "d1",
  verbose: true,
  strict: true
})

The idea is that you just run pnpx d1zard and then select what you actually want to do. It should be enough idiot proof, that someone who just pulled an example template from framework website like (next or nuxt) could simply fallow along and make it work without reaching out to Cloudflare Docs.

@clibequilibrium
Copy link

clibequilibrium commented Apr 12, 2024

So, I have an idea, what about making a CLI tool (maybe call it d1zard). It would use underlying CLI tools like wrangler d1. It would be an experiment, to push UX to the limits. If it works out, it could be merged back intro wrangler.

d1zard pretty much shows you the current state of your D1s in you project, and gives you options to work with it.

  • You can run it simply by pnpx d1zard without installing

  • It uses your wrangler.toml, or recommends you to use it instead of passing parameters via CLI

  • it updates env.d.ts for you too if CloudflareEnv present in env.d.ts

  • It lists currently bound D1s and lets you to bind or create a new one

    • it has the ability, to list D1s from your CF Account
  • Changes are saved back to wrangler.toml

  • (optional nice to have) It could have support for drizzle/prisma too, which would replace wrangler d1 migrations create with drizzle-kit generate:sqlite or prisma counterpart. Or maybe even create default file like this:

// Path: drizzle.config.ts
import { defineConfig } from "drizzle-kit"

export default defineConfig({
  schema: "./drizzle/schema.ts",
  out: "./migrations",
  driver: "d1",
  verbose: true,
  strict: true
})

The idea is that you just run pnpx d1zard and then select what you actually want to do. It should be enough idiot proof, that someone who just pulled an example template from framework website like (next or nuxt) could simply fallow along and make it work without reaching out to Cloudflare Docs.

This looks great but it sems that d1zard does too much aside of showing the current state of D1 project. Also as D1 and Drizzle user I have no issues generate migrations with the kit and then apply them with wrangler. Not sure that is a painful problem to solve. I would narrow down d1zard to focus on UX as you stated, display D1 metrics easily etc.

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