Database migrations for your Go project. Supports files, functions, and query migrations.
Version: 0.2.0
Project Links: Docs - Issues - Mailing List - Contributing
Author: Peter Sanchez (https://petersanchez.com)
This is a simple tool to manage database migrations from within your Go project. It's not a CLI tool, but a module that you plugin to your own project as needed.
It's based on github.com/joncalhoun/migrate but I've done many changes to make it fit my needs. That is why I am just maintaining my own fork versus submitting a PR. I feel mine has diverged too far from what Jon originally wanted.
Here's some of the changes:
context.Context
within migrations.context.Context
) per migration.My fork is a copy of the original repo as of this commit. I probably
should have done a repo migration to Mercurial but here we are. All code up to
the commit above is licensed under the MIT license, see the PREVIOUS_LICENSES
document.
This example will assume you're using PostgreSQL as well (note the changing of
binding type to migrate.DOLLAR
).
Let's say you have a simple directory structure like so:
.
├── accounts
│ ├── input.go
│ ├── models.go
│ ├── routes.go
├── cmd
│ └── webapp
│ └── main.go
├── go.mod
├── go.sum
├── webapp_binary
├── Makefile
├── migrations
│ ├── 0001_initial_rollback.sql
│ └── 0001_initial.sql
├── templates
├── login.html
└── register.html
You can see there is a migrations
directory. You can store your migration
files anywhere you want, but in this example we'll store them there.
Now let's add migrations to the main binary. We'll edit cmd/webapp/main.go
to
always call migrations when starting. I'm not recommending this, just a simple
example.
import (
...
"petersanchez.com/x/migrate",
...
)
func main() {
// `db` is your database connection (*sql.DB)
// Custom functions should be watching for the context's Done() channel
migrations := []migrate.Migration{
migrate.FileMigration("0001_initial", "migrations/0001_initial.sql", "migrations/0001_initial_rollback.sql", 0),
migrate.Migration{
ID: "0002_function",
Migrate: func(ctx context.Context, tx *sql.Tx) error {
// Run your migrate code here.
return nil
},
Rollback: func(ctx context.Context, tx *sql.Tx) error {
// Run your rollback code here.
return nil
},
Timeout: 40, // Set a 40 second timeout on the functions
},
}
if len(os.Args) > 0 {
if os.Args[1] != "migrate" {
err := migrate.Command(db, migrations, migrate.DOLLAR)
// handle err
os.Exit(0)
}
}
// rest of your main() code
}
I found the larger database migration projects for Go to be overkill for my needs. Especially if you wanted to run custom function migrations.
During my research I stumbled on an article titled Database migrations in Go by Jon Calhoun. I had already been thinking of how to create my own migrations package as minimally as possible and this article was close enough to what I was thinking. John even created the original migrate package, but it lacked several things I wanted in my migration solution.
So I stripped out external dependencies, added a bunch of stuff I wanted, and a few development hours later, here we are.
My needs are fairly simple and the current state of the module basically covers them. Please submit bugs and/or patches if you find any issues.
We accept patches submitted via hg email
which is the patchbomb
extension
included with Mercurial.
The mailing list where you submit your patches is
~petersanchez/public-inbox@lists.code.netlandish.com
. You can also view the
archives on the web here:
https://lists.code.netlandish.com/~petersanchez/public-inbox
To quickly setup your clone of migrate
to submit to the mailing
list just edit your .hg/hgrc
file and add the following:
[email]
to = ~petersanchez/public-inbox@lists.code.netlandish.com
[patchbomb]
flagtemplate = {separate(' ', 'migrate', flags)}
[diff]
git = 1
We have more information on the topic here:
All documentation, libraries, and sample code are Copyright 2022 Peter Sanchez <pjs@petersanchez.com>. The library and sample code are made available to you under the terms of the BSD license which is contained in the included file, LICENSE.