Skip to content
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

Are Goose migrations possible anymore? #701

Open
thefinn93 opened this issue Dec 23, 2024 · 2 comments
Open

Are Goose migrations possible anymore? #701

thefinn93 opened this issue Dec 23, 2024 · 2 comments

Comments

@thefinn93
Copy link

Hello! I'm trying to use River with my existing database, which is migrated with Goose. The River docs offer an example of how to do this. When I went to implement it, the Goose API had changed a little so I had to make some minor modifications, but was surprised to find that the River method (MigrateTx) is deprecated in 3ed1d29 because the migrations can no longer be performed in a single transaction.

I'm wondering if there's a recommended path forward with Goose, and letting you know that the information in your docs seems to be outdated.

@bgentry
Copy link
Contributor

bgentry commented Dec 24, 2024

@thefinn93 thanks for pointing this out! As #600 details there are certain sequences of migrations which can't all be run in a single transaction, which was the reason for the change. The migrator now internally opens a new transaction for each migration in the sequence.

We actually use Goose migrations via embedded SQL files and these work just fine with the new setup because Goose also opens a transaction per migration instead of running them all in one txn. I think it should still be possible to use Goose's Go API for this, although it might be a little more awkward. In particular I believe you'd use AddMigrationNoTxContext to add a function which constructs a riverdatabasesql driver from the provided sql.DB, creates a Migrator, and calls Migrate on it (likely with a specified max version so its behavior doesn't change if new migrations are added).

I don't have time to put together a full example of this today due to the holiday, but I suspect it should work well despite being a little ugly. Is this something you could give a try and then report back on? It would help having a full tested example for figuring out how to document it and whether there are any rough edges that we could smooth out.

Cheers 🎄 🎅

@thefinn93
Copy link
Author

Thanks, I did some testing after filing this and found AddMigrationNoTxContext. I want to test further but this seems like it will work to get us up to the current river migration.

package migrations

import (
	"context"
	"database/sql"

	goose "github.com/pressly/goose/v3"
	"github.com/riverqueue/river/riverdriver/riverdatabasesql"
	"github.com/riverqueue/river/rivermigrate"
)

func init() {
	// I assume this has to be adjusted to match the right number, I'm not actually sure how Goose handles these go migrations
	goose.AddMigrationNoTxContext(Up003, Down003)
}

func Up003(ctx context.Context, db *sql.DB) error {
	migrator, err := rivermigrate.New(riverdatabasesql.New(db), nil)
	if err != nil {
		return err
	}

	_, err = migrator.Migrate(ctx, rivermigrate.DirectionUp, &rivermigrate.MigrateOpts{
		TargetVersion: 6,
	})
	return err
}

func Down003(ctx context.Context, db *sql.DB) error {
	migrator, err := rivermigrate.New(riverdatabasesql.New(db), nil)
	if err != nil {
		return err
	}

	// TargetVersion -1 removes River's schema completely.
	_, err = migrator.Migrate(ctx, rivermigrate.DirectionDown, &rivermigrate.MigrateOpts{
		TargetVersion: -1,
	})
	return err
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants