-
-
Notifications
You must be signed in to change notification settings - Fork 233
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
cmd/bundb: Bun CLI for database schema management #1062
base: master
Are you sure you want to change the base?
Conversation
Using plugin looks interesting, but risky and it does not work on Windows :( But I actually had similar idea. An alternative can be to provide package buncli
func New(options ...Option) *cli.App {} And then we can provide some command that creates an initial app structure/dirs or just some repo with a bunch of folders/files that uses the package main
import "github.com/uptace/bun/buncli"
func main() {
app := buncli.New(buncli.WithAutoMigrator(...))
app.Run()
} Then user can directly modify WDYT? |
Sharing this really useful summary of caveats to look out for from someone who tried using the plugins productively.
Yep, that's the way to go, I'll focus on this approach. |
3bbeb69
to
4967e7c
Compare
Here we introduce bundb auto migrate command to create and run migrations from the CLI. It works by importing the Models from a pre-build user plugin, similarly to how Migrator gets the list of migrations by being compiled together with the user's package. The difference here is that bundb can be distributed as a standalone binary and only requires users to set up the migrations/main.go file.
This will remove the need for users to do any extra steps before using bundb. Provide -rebuild flag to force rebuild and -cleanup to remove the dangling plugin file.
Improved error handling during 'go build' step to output a more user-friendly message.
Users can start the tool from their own entrypoints by using buncli.New/Run etc. They are also responsible for configuring the DB connection and AutoMigrator. bundb/bunctl will eventually use FromPlugin() to read config from a pre-built plugin.
- migrate - rollback - create - unlock
77e6497
to
3d4032c
Compare
The bootstrapped CLI which will be compiled along with the rest of the user migration files does not need the Init command. On the other hand, the standalone bundb command will provide that and exclude all other commands to avoid confusion between them.
Experimental commans are the good old [auto, migrate, rollback, etc.] but adapted to import configuration from a pre-built plugin. Plugins are known to be unstable and only sometimes work correctly, so this feature is more of a proof of concept and we should probably add the option to disable it entirely with build tags (for standalone bundb). TODO:: bun init --plugin does not initialize a Go module in the migrations/ directory. Currently one would need to manually run go mod init and go mod tidy after bootstraping the project.
Summary
$ bundb -h NAME: bundb - Database migration tool for uptrace/bun USAGE: bundb [global options] command [command options] COMMANDS: auto manage database schema with AutoMigrator help, h Shows a list of commands or help for one command GLOBAL OPTIONS: --help, -h show help
Motivation
To provide a default CLI utility for Bun users to interact with (Auto-)Migrator. Our Migrations guide currently has users build their own binary, but it would be great to eliminate this step for those that do not have any special logic on top of "my models have changed, please generate migrations for it".
Related proposal: #875
Implementation
As per the current docs, the migration binary has to be co-located with the user's
migrations/
package and compiled together to access the registered / discovered migrations:To distribute
bundb
as a standalone binary, we need to be able to load objects from the users' packages dynamically. This is achieved by leveragingplugin
package from the Go's standard library. The implementation details are handled bybundb
(it will build the user's package in-buildmode=plugin
to then be able to import symbols from it at runtime), so that the users won't have to deal with any of it.The setup required to use AutoMigrator is only a little different from the current on:
Bonus: this method works for accessing
Migrations
and using them with the usual Migrator pretty much out of the box.Besides that, this is a just a plain old CLI built with
urfave/cli/v2
.How to test locally
After checking out this branch locally:
main.go
file:Example main.go
Declare Bun models which AutoMigrator should target:
bundb
out:Discussion
Currently
Models []interface{}
is the only AutoMigrator configuration that's expressed "in Go" and other options can be passed via command-line flags. Do we want to also allow the users to configure their own AutoMigrator completely (including the database connections, etc) themselves and just export it in theirmigrations
package?I.e. use
migrations.AutoMigrator
if one is exported., ignoring all related CLI options?How much logging do we want? I'm thinking:
"created 2 migration files: 20240301_public.up.sql and 20240301_public.down.sql"
or `"nothing to migrate, ok"-v | --verbose
to enable query logging (setBUNDEBUG=2
) or something like that--silent
to disable logging altogetherFor example, the user runs
bundb init --create-directory=db-migrations
. If we storedirectory=db-migrations
in a local config file, they can run subsequent commands without passing any flags:bundb auto migrate
.If a config file sounds like an overkill, we could store these to the env variables (those won't be persisted between shell sessions)
On the naming
We didn't want to potentially clash with bun.js CLI, we decided to add some sort of a qualified, e.g. "bungo".
Then I saw that migrate example calls its application
bun db
, so I borrowed it directly from there, omitting the space.