{"id":15292913,"url":"https://github.com/trivigy/migrate","last_synced_at":"2025-10-07T06:30:31.058Z","repository":{"id":38329483,"uuid":"191445321","full_name":"trivigy/migrate","owner":"trivigy","description":"Idiomatic GO cluster release and database migration management","archived":true,"fork":false,"pushed_at":"2023-05-11T20:39:34.000Z","size":626,"stargazers_count":2,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-10-01T16:31:25.189Z","etag":null,"topics":["database","embedded","gcloud","kubernetes","migration","semver","sql","tool"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/trivigy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-06-11T20:34:44.000Z","updated_at":"2023-06-26T18:38:28.000Z","dependencies_parsed_at":"2024-06-19T05:19:44.045Z","dependency_job_id":"a2014439-83e7-4487-82ad-6e2d31b400c9","html_url":"https://github.com/trivigy/migrate","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivigy%2Fmigrate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivigy%2Fmigrate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivigy%2Fmigrate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/trivigy%2Fmigrate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/trivigy","download_url":"https://codeload.github.com/trivigy/migrate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":235599557,"owners_count":19016190,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["database","embedded","gcloud","kubernetes","migration","semver","sql","tool"],"created_at":"2024-09-30T16:31:38.608Z","updated_at":"2025-10-07T06:30:25.680Z","avatar_url":"https://github.com/trivigy.png","language":"Go","readme":"# Migrate\n\n[![CircleCI branch](https://img.shields.io/circleci/project/github/trivigy/migrate/master.svg?label=master\u0026logo=circleci)](https://circleci.com/gh/trivigy/workflows/migrate)\n[![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE.md)\n[![](https://godoc.org/github.com/trivigy/migrate?status.svg\u0026style=flat)](http://godoc.org/github.com/trivigy/migrate)\n[![GitHub tag (latest SemVer)](https://img.shields.io/github/tag/trivigy/migrate.svg?style=flat\u0026color=e36397\u0026label=release)](https://github.com/trivigy/migrate/releases/latest)\n\nThe library was originally forked from [sql-migrate](https://github.com/rubenv/sql-migrate) \nwhich is a really great project. However I needed a tool that is somewhat more \ngolang idiomatic in nature. So I completely re-wrote the API for the forked \nlibrary and optimized on a whole lot of stuff inside. I am using this project to \nback a few other major developments I am working on and will keep updating things \nas needed. If you do find bugs please feel free to submit a pull request.\n\n## Notice\n\u003e Version 2.0 is quiet different from the original fork and is the one I use in production for projects I support. It comes with kubernetes releases as migrations. Think helm but in pure golang in-code manifests. This doc below doesn't reflect those changes almost at all. Feel free to explore the code under the different tag and ask questions. Whenever I get some time I will update this doc and create an example illustrating how all that works.\n\n## Features\n* Usable as an embedded CLI tool\n* Supports SQLite, PostgreSQL, MySQL, MSSQL (through [gorp](https://github.com/go-gorp/gorp))\n* Migrations are defined with SQL for full flexibility\n* Transaction based migrations with ability to run transactionless\n* Migration rollback support through `up` and `down` commands\n* Supports multiple database types in one project\n\n## Installation\nTo embed the application, use the following from within your project directory:\n```bash\ngo get -u github.com/trivigy/migrate\n```\n\n## Usage\nThe way the library works is purely through embedding it in another project as \na runnable `cmd`. You can then create multiple of these for different databases \nthat your project supports.\n\nFor example here is a possible project structure where this tool would be embedded:\n```\n$ tree ./project\n./project\n.\n├── cmd\n│   └── migrate\n│       └── main.go\n├── go.mod\n├── go.sum\n├── internal\n│   └── migrations\n│       ├── 0.0.1_create-users-table.go\n│       ├── 0.0.2_create-emails-table.go\n│       └── 0.0.3_create-zipcodes-table.go\n├── README.md\n└── main.go\n```\n\nIn this case your main project is inside of `main.go` located at the tree root. \nYou will then follow by creating the `./cmd/migrate` folder and adding a `main.go` \nfile there. Here is an example of what should be added to that file.\n\n\u003e There is absolutely no requirement to call the embedded application `migrate`.\nIn fact if you are using multiple migration setups, you will have to create a \nfew of these and call them differently.\n\n\u003e Skip down here if you just want to see how to write migrations [HERE]()\n\n### `./cmd/migrate/main.go`\n```\npackage main\n\nimport (\n\t\"os\"\n\n\t\"github.com/trivigy/migrate\"\n\n\t_ \"github.com/username/project/internal/migrations\"\n)\n\nfunc init() {\n\tmigrate.SetConfigs(map[string]migrate.DataSource{\n\t\t\"development\": {\n\t\t\tDriver: \"postgres\",\n\t\t\tSource: \"host=127.0.0.1 user=postgres dbname=database sslmode=disable\",\n\t\t},\n\t})\n}\n\nfunc main() {\n\tif err := migrate.Execute(); err != nil {\n\t\tos.Exit(1)\n\t}\n}\n\n```\n\n\u003e Most important part here is to add the `main()` function with that exact call \nto `migrate.Execute()`. Once you do that, you can run the embedded command to \nhelp you do the rest.\n\nAs you can see, the configuration for the tool are done programmically through \n`migrate.SetConfigs()`. The key of the passed map acts as the environment name. \nYou later reference it when calling different commands. The environment names \ncan be anything you want. In this case I chose to call it `development`.\n\nCurrently `SQLite`, `PostgreSQL`, `MySQL`, `MSSQL` drivers are supported and the \nvalues of `driver` and `source` are passed varbatum down to `sql.Open(driver, source)`. \nThus the format for `source` is depended on the type of the database.\n\nUse `--help` to learn about what commands you can run:\n```\n$ go run ./cmd/migrate --help\nIdiomatic GO database migration tool\n\nUsage:\n  main [command]\n\nAvailable Commands:\n  create      Create a newly versioned migration template file\n  down        Undo the last applied database migration\n  status      Show migration status for the current database\n  up          Migrates the database to the most recent version\n\nFlags:\n  -v, --version   Print version information and quit.\n      --help      Show help information.\n\nUse \"main [command] --help\" for more information about a command.\n```\n\nUse the `--help` flag in combination with any of the commands to get an overview of its usage:\n```\n$ go run ./cmd/migrate up --help\nMigrates the database to the most recent version\n\nUsage:\n  main up [flags]\n\nFlags:\n      --dry-run      Simulate a migration printing planned queries.\n  -n, --num NUMBER   Indicate NUMBER of migrations to apply.\n  -e, --env ENV      Run with configurations named ENV. (required)\n      --help         Show help information.\n```\n\n## MySQL Caveat\n\nIf you are using MySQL, you must append `?parseTime=true` to the source DSN \nconfiguration. See [here](https://github.com/go-sql-driver/mysql#parsetime) for \nmore information. For example:\n### alternative `./cmd/migrate/main.go`\n```\npackage main\n\nimport (\n\t\"os\"\n\n\t\"github.com/trivigy/migrate\"\n\n\t_ \"github.com/username/project/internal/migrations\"\n)\n\nfunc init() {\n\tmigrate.SetConfigs(map[string]migrate.DataSource{\n\t\t\"testing\": {\n\t\t\tDriver: \"mysql\",\n\t\t\tSource: \"root@/dbname?parseTime=true\",\n\t\t},\n\t})\n}\n\nfunc main() {\n\tif err := migrate.Execute(); err != nil {\n\t\tos.Exit(1)\n\t}\n}\n\n```\n\n## Writing Migrations\nMigrations are embedded into the command by referencing them with \n`import _ \"github.com/username/project/internal/migrations\"`. You might have \nnoticed this from the `./cmd/migrate/main.go` examples above. I am chosing to \nplace the migration files inside `./internal/migrations` but in face you may \nchose to place them elsewhere.\n\nTo help you create migration files quicker, there is the `create` command. What \nis special about it is that it will auto-increment the migration version tags \nwhich need to be unique.\n```\n$ go run ./cmd/migrate create --help\nCreate a newly versioned migration template file\n\nUsage:\n  main create NAME[:TAG] [flags]\n\nFlags:\n  -d, --dir PATH   Specify directory PATH to create miration file. (default \".\")\n      --help       Show help information.\n```\n\nThe tags follow an almost complete semver model. You can use `major`, `minor`, \n`patch`, and `build` parts of the semantic versioning scheme to tag your \nmigrations. The migrations get sorted based on this semantic tagging scheme. For \nmore detail on the precedence order read [semver](https://semver.org/).\n\nAn example migration file might look like this:\n```\n$ cat ./internal/migrations/0.0.4_create-zipcodes-table.go \npackage migrations\n\nimport (\n        \"github.com/trivigy/migrate\"\n)\n\nfunc init() {\n        migrate.Append(migrate.Migration{\n                Tag: \"0.0.4\",\n                Up: []migrate.Operation{\n                        {Query: `CREATE TABLE zipcodes (id int)`},\n                },\n                Down: []migrate.Operation{\n                        {Query: `DROP TABLE zipcodes`},\n                },\n        })\n}\n```\nThe filename for the migration files **DO NOT** follow a strict naming convention \nof `{tag}_{filename}.go`. The actual filename is there just to help the developer \ncommunicate file purpose. However, when using the `create` command filenames are \ngenerated with that name.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrivigy%2Fmigrate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftrivigy%2Fmigrate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftrivigy%2Fmigrate/lists"}