Skip to content

topi314/gomigrate

Repository files navigation

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.

About

Golang SQL database schema migration library

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Languages