gomigrate

package module
v0.0.0-...-f3f6e21 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 4, 2025 License: Apache-2.0 Imports: 10 Imported by: 1

README

Go Reference Go Report Go Version License GoMigrate Version

gomigrate

GoMigrate is a SQL migration library for Go. It can support multiple databases such as SQLite, PostgreSQL, MySQL, and others.

Table of Contents

Click to expand

Getting Started

Prerequisites
  • Go 1.24 or later
  • SQLite, PostgreSQL, MySQL, or other databases
  • Go driver for the database you want to use
Installing
go get github.com/topi314/gomigrate

Usage

Create a migrations

Create a new folder named migrations and create a file with the following naming convention VERSION_NAME.sql (VERSION_NAME.DRIVER.sql) where VERSION is a number, NAME is a name of the migration & DRIVER (optional) is the name of the database driver this migration is for. As an example: 01_create_users_table.sql, 01_create_users_table.postgres.sql, 02_add_email_to_users_table.sql or 02_add_email_to_users_table.sqlite.sql.

01_create_users_table.sql

-- create users table
CREATE TABLE users
(
    id   SERIAL PRIMARY KEY,
    name VARCHAR NOT NULL
);

01_create_users_table.postgres.sql

-- create users table for PostgreSQL
CREATE TABLE users
(
    id   SERIAL PRIMARY KEY,
    name VARCHAR NOT NULL
);

02_add_email_to_users_table.sql

-- add email column to users table
ALTER TABLE users
    ADD COLUMN email VARCHAR;

02_add_email_to_users_table.sqlite.sql

-- add email column to users table for SQLite
ALTER TABLE users
    ADD COLUMN email VARCHAR;

It should look like this:

migrations/
├─ 01_create_users_table.sql
├─ 01_create_users_table.postgres.sql
├─ 02_add_email_to_users_table.sql
├─ 02_add_email_to_users_table.sqlite.sql

Alternatively you can also organize your migrations into dirver subdirectories:

migrations/
├─ postgres/
│  ├─ 01_create_users_table.sql
│  ├─ 02_add_email_to_users_table.sql
├─ sqlite/
│  ├─ 01_create_users_table.sql
│  ├─ 02_add_email_to_users_table.sql

In this case no DRIVER suffix is allowed in the migration file name.

Run migrations

Now you can run the migrations in your Go code. Here is an example for SQLite:

package main

import (
	"context"
	"database/sql"
	"embed"
	"log"
	"log/slog"
	"time"

	_ "modernc.org/sqlite"

	"github.com/topi314/gomigrate"
	"github.com/topi314/gomigrate/drivers/sqlite"
)

//go:embed migrations/*.sql
var migrations embed.FS

func main() {
	// open database
	db, err := sql.Open("sqlite", "database.db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// create context with timeout
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// run migrations
	if err = gomigrate.Migrate(ctx, db, sqlite.New, migrations,
		gomigrate.WithDirectory("migrations"), // set directory for migrations
		gomigrate.WithTableName("gomigrate"),  // set custom table name for migrations
		gomigrate.WithLogger(slog.Default()),  // set custom logger
	); err != nil {
		log.Fatal(err)
	}

	// run your code
}

Examples

You can find examples under

Troubleshooting

For help feel free to open an issue.

Contributing

Contributions are welcomed but for bigger changes please first create an issue to discuss your intentions and ideas.

License

Distributed under the License. See LICENSE for more information.

Documentation

Overview

Package gomigrate is a simple migration tool for Go projects. It reads SQL migrations from files and executes them in a transaction. It also keeps track of the executed migrations in a table.

Usage:

package main

import (
	"context"
	"database/sql"
	"embed"
	"log"
	"log/slog"
	"time"

	_ "modernc.org/sqlite"

	"github.com/topi314/gomigrate"
	"github.com/topi314/gomigrate/drivers/sqlite"
)

//go:embed migrations/*.sql
var migrations embed.FS

func main() {
	// open database
	db, err := sql.Open("sqlite", "database.db")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// create context with timeout
	ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
	defer cancel()

	// run migrations
	if err = gomigrate.Migrate(ctx, db, sqlite.New, migrations,
		gomigrate.WithDirectory("migrations"), // set directory for migrations
		gomigrate.WithTableName("gomigrate"),  // set custom table name for migrations
		gomigrate.WithLogger(slog.Default()),  // set custom logger
	); err != nil {
		log.Fatal(err)
	}

	// run your code
}

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNoDatabase is returned when no database is provided.
	ErrNoDatabase = errors.New("no database provided")

	// ErrNoDriver is returned when no driver is provided.
	ErrNoDriver = errors.New("no driver provided")
)

Functions

func Migrate

func Migrate(ctx context.Context, db Queryer, newDriver NewDriver, disk fs.FS, opts ...Option) error

Migrate reads and executes SQL migrations from the embed.FS to bring the database schema up to date. It keeps track of the executed migrations in a table. If the database schema is ahead of the migrations, it will return an error. Each migration runs in a transaction. If the context is canceled, the transaction for the current migration will be rolled back, and it will return an error.

Types

type Driver

type Driver interface {
	// Name returns the name of the driver.
	Name() string

	// CreateVersionTable creates the versioning table if it does not exist.
	CreateVersionTable(ctx context.Context) error

	// GetVersion returns the most recent schema version.
	GetVersion(ctx context.Context) (int, error)

	// AddVersion adds a new schema version to the versioning table.
	AddVersion(ctx context.Context, tx *sql.Tx, version int) error
}

Driver allows gomigrate to work with different databases such as SQLite and PostgreSQL.

type MigrateError

type MigrateError struct {
	Name     string
	FileName string
	Version  int
	Err      error
}

MigrateError holds additional information about an error that occurred during migration.

func (*MigrateError) Error

func (e *MigrateError) Error() string

Error returns the error message.

func (*MigrateError) Unwrap

func (e *MigrateError) Unwrap() error

Unwrap returns the underlying error.

type NewDriver

type NewDriver func(db Queryer, tableName string) Driver

NewDriver is a function that returns a new Driver.

type Option

type Option interface {
	// contains filtered or unexported methods
}

Option can be used to configure the migrator.

func WithDirectory

func WithDirectory(dir string) Option

WithDirectory sets the directory where the migration files are loaded from.

func WithLogger

func WithLogger(l *slog.Logger) Option

WithLogger sets the logger to be used by the migrator.

func WithTableName

func WithTableName(name string) Option

WithTableName sets the name of the table where the schema version is stored.

func WithoutDirectory

func WithoutDirectory() Option

WithoutDirectory removed the default directory where the migration files are loaded from.

type Queryer

type Queryer interface {
	// QueryContext executes a query that returns rows, typically a SELECT.
	// The args are for any placeholder parameters in the query.
	QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error)

	// ExecContext executes a query without returning any rows.
	// The args are for any placeholder parameters in the query.
	ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)

	// BeginTx starts a transaction.
	//
	// The provided context is used until the transaction is committed or rolled back.
	// If the context is canceled, the sql package will roll back
	// the transaction. [Tx.Commit] will return an error if the context provided to
	// BeginTx is canceled.
	//
	// The provided [sql.TxOptions] is optional and may be nil if defaults should be used.
	// If a non-default isolation level is used that the driver doesn't support,
	// an error will be returned.
	BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
}

Queryer is used to execute SQL queries and transactions.

Directories

Path Synopsis
drivers

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL