goose
goose copied to clipboard
Go migrations don't work without migrations directory
Steps to reproduce:
- use go migrations
- build application
- don't put application code to docker container
- run migrations on server
Expected result: Migration success.
Actual result: Error: "migration directory does not exists".
#143 removed the runtime check for .sql files directory presence. I believe this is very unsafe operation; since any user's misconfiguration might yield into silent but serious issues.
I'd consider three alternatives:
- document the behaviour and explain users to inject empty temporary directory
$(mktemp -d)
if they need this - add a special path that always exists; but is a no-op, ie.
"/dev/null"
- add a global setter function, ie.
goose.RunSQLMigrations(false)
(true
by default), to change the default goose behaviour
feedback welcome
Duplicate PR that predated #143 but suffered from the same symptoms: #107
+1 for goose.RunSQLMigrations(false)
alternative.
What do you think about @damour proposal #143 to use strategies (goose.UpWithCollector(...)
)?
I personally am a fan of exposing a goose.Registered
API, that gives you some control over registeredGoMigrations
For example, the simplest compiled migration binary would look like:
package main
import (
"database/sql"
"log"
"os"
"github.com/pressly/goose"
_ "migrations"
)
func main() {
dbstring := os.Args[1]
db, err := sql.Open("postgres", dbstring)
if err != nil {
log.Fatalf("goose: failed to open DB: %v\n", err)
}
err := goose.Registered().Up(db)
if err != nil {
log.Fatalln(err)
}
}
The returned Registered type could have a few other methods to give additional information to developers, such as:
- Count of migrations that are registered
- Latest version of registered migrations
Would love to see more input and build some sort of directions for this
Bump.
I'm really wanting to push forward with a solution here, but drastically require some user input on the proposed solution.
This issue should be resolved with the Provider
. It takes 3 arguments:
- the dialect: sqlite, postgres, mysql, etc.
- a db connection:
*sql.DB
- optional, a
fs.FS
(filesystem)
Given 3 is optional, it allows you to register Go migrations either globally or with the Provider
directly using goose.WithGoMigrations
option. ps. There is now also a goose.NewGoMigration
constructor to simplify creating Go migrations.
If you're interested to learn more about the Provider
, check out the post we recently published.
https://pressly.github.io/goose/blog/2023/goose-provider/
Closing the issue, but feel free to drop a comment if this issue has not been resolved for you.