{"id":13412053,"url":"https://github.com/larapulse/migrator","last_synced_at":"2025-04-08T00:31:37.238Z","repository":{"id":39759149,"uuid":"275391249","full_name":"larapulse/migrator","owner":"larapulse","description":"MySQL database migrator","archived":false,"fork":false,"pushed_at":"2022-07-21T21:48:23.000Z","size":137,"stargazers_count":25,"open_issues_count":0,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-11-07T09:20:20.088Z","etag":null,"topics":["golang","migration","mysql"],"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/larapulse.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}},"created_at":"2020-06-27T14:40:29.000Z","updated_at":"2024-05-19T07:31:13.000Z","dependencies_parsed_at":"2022-07-13T15:31:35.062Z","dependency_job_id":null,"html_url":"https://github.com/larapulse/migrator","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larapulse%2Fmigrator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larapulse%2Fmigrator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larapulse%2Fmigrator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larapulse%2Fmigrator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/larapulse","download_url":"https://codeload.github.com/larapulse/migrator/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247755338,"owners_count":20990616,"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":["golang","migration","mysql"],"created_at":"2024-07-30T20:01:20.542Z","updated_at":"2025-04-08T00:31:36.873Z","avatar_url":"https://github.com/larapulse.png","language":"Go","readme":"# MySQL database migrator\n\n\u003cimg align=\"right\" width=\"159px\" src=\"https://github.com/larapulse/migrator/blob/master/logo.png\"\u003e\n\n[![Build Status](https://travis-ci.org/larapulse/migrator.svg)](https://travis-ci.org/larapulse/migrator)\n[![Software License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](LICENSE.md)\n[![codecov](https://codecov.io/gh/larapulse/migrator/branch/master/graph/badge.svg)](https://codecov.io/gh/larapulse/migrator)\n[![Go Report Card](https://goreportcard.com/badge/github.com/larapulse/migrator)](https://goreportcard.com/report/github.com/larapulse/migrator)\n[![GoDoc](https://godoc.org/github.com/larapulse/migrator?status.svg)](https://pkg.go.dev/github.com/larapulse/migrator?tab=doc)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\n[![Release](https://img.shields.io/github/release/larapulse/migrator.svg)](https://github.com/larapulse/migrator/releases)\n[![TODOs](https://badgen.net/https/api.tickgit.com/badgen/github.com/larapulse/migrator)](https://www.tickgit.com/browse?repo=github.com/larapulse/migrator)\n\nMySQL database migrator designed to run migrations to your features and manage database schema update with intuitive go code. It is compatible with the latest MySQL v8.\n\n## Installation\n\nTo install `migrator` package, you need to install Go and set your Go workspace first.\n\n1. The first need [Go](https://golang.org/) installed (**version 1.13+ is required**), then you can use the below Go command to install `migrator`.\n\n```sh\n$ go get -u github.com/larapulse/migrator\n```\n\n2. Import it in your code:\n\n```go\nimport \"github.com/larapulse/migrator\"\n```\n\n## Quick start\n\nInitialize migrator with migration entries:\n\n```go\nvar migrations = []migrator.Migration{\n\t{\n\t\tName: \"19700101_0001_create_posts_table\",\n\t\tUp: func() migrator.Schema {\n\t\t\tvar s migrator.Schema\n\t\t\tposts := migrator.Table{Name: \"posts\"}\n\n\t\t\tposts.UniqueID(\"id\")\n\t\t\tposts.Varchar(\"title\", 64)\n\t\t\tposts.Text(\"content\", false)\n\t\t\tposts.Timestamps()\n\n\t\t\ts.CreateTable(posts)\n\n\t\t\treturn s\n\t\t},\n\t\tDown: func() migrator.Schema {\n\t\t\tvar s migrator.Schema\n\n\t\t\ts.DropTableIfExists(\"posts\")\n\n\t\t\treturn s\n\t\t},\n\t},\n\t{\n\t\tName: \"19700101_0002_create_comments_table\",\n\t\tUp: func() migrator.Schema {\n\t\t\tvar s migrator.Schema\n\t\t\tcomments := migrator.Table{Name: \"comments\"}\n\n\t\t\tcomments.UniqueID(\"id\")\n\t\t\tcomments.UUID(\"post_id\", \"\", false)\n\t\t\tcomments.Varchar(\"name\", 64)\n\t\t\tcomments.Column(\"email\", migrator.String{Default: \"\u003cnil\u003e\"})\n\t\t\tcomments.Text(\"content\", false)\n\t\t\tcomments.Timestamps()\n\n\t\t\tcomments.Foreign(\"post_id\", \"id\", \"posts\", \"RESTRICT\", \"RESTRICT\")\n\n\t\t\ts.CreateTable(comments)\n\n\t\t\treturn s\n\t\t},\n\t\tDown: func() migrator.Schema {\n\t\t\tvar s migrator.Schema\n\n\t\t\ts.DropTableIfExists(\"comments\")\n\n\t\t\treturn s\n\t\t},\n\t},\n\t{\n\t\tName: \"19700101_0003_rename_foreign_key\",\n\t\tUp: func() migrator.Schema {\n\t\t\tvar s migrator.Schema\n\n\t\t\tkeyName := migrator.BuildForeignNameOnTable(\"comments\", \"post_id\")\n\t\t\tnewKeyName := migrator.BuildForeignNameOnTable(\"comments\", \"article_id\")\n\n\t\t\ts.AlterTable(\"comments\", migrator.TableCommands{\n\t\t\t\tmigrator.DropForeignCommand(keyName),\n\t\t\t\tmigrator.DropIndexCommand(keyName),\n\t\t\t\tmigrator.RenameColumnCommand{\"post_id\", \"article_id\"},\n\t\t\t\tmigrator.AddIndexCommand{newKeyName, []string{\"article_id\"}},\n\t\t\t\tmigrator.AddForeignCommand{migrator.Foreign{\n\t\t\t\t\tKey:       newKeyName,\n\t\t\t\t\tColumn:    \"article_id\",\n\t\t\t\t\tReference: \"id\",\n\t\t\t\t\tOn:        \"posts\",\n\t\t\t\t}},\n\t\t\t})\n\n\t\t\treturn s\n\t\t},\n\t\tDown: func() migrator.Schema {\n\t\t\tvar s migrator.Schema\n\n\t\t\tkeyName := migrator.BuildForeignNameOnTable(\"comments\", \"article_id\")\n\t\t\tnewKeyName := migrator.BuildForeignNameOnTable(\"comments\", \"post_id\")\n\n\t\t\ts.AlterTable(\"comments\", migrator.TableCommands{\n\t\t\t\tmigrator.DropForeignCommand(keyName),\n\t\t\t\tmigrator.DropIndexCommand(keyName),\n\t\t\t\tmigrator.RenameColumnCommand{\"article_id\", \"post_id\"},\n\t\t\t\tmigrator.AddIndexCommand{newKeyName, []string{\"post_id\"}},\n\t\t\t\tmigrator.AddForeignCommand{migrator.Foreign{\n\t\t\t\t\tKey:       newKeyName,\n\t\t\t\t\tColumn:    \"post_id\",\n\t\t\t\t\tReference: \"id\",\n\t\t\t\t\tOn:        \"posts\",\n\t\t\t\t}},\n\t\t\t})\n\n\t\t\treturn s\n\t},\n}\n\nm := migrator.Migrator{Pool: migrations}\nmigrated, err = m.Migrate(db)\n\nif err != nil {\n\tlog.Errorf(\"Could not migrate: %v\", err)\n\tos.Exit(1)\n}\n\nif len(migrated) == 0 {\n\tlog.Print(\"Nothing were migrated.\")\n}\n\nfor _, m := range migrated {\n\tlog.Printf(\"Migration: %s was migrated ✅\", m)\n}\n\nlog.Print(\"Migration did run successfully\")\n```\n\nAfter the first migration run, `migrations` table will be created:\n\n```\n+----+-------------------------------------+-------+----------------------------+\n| id | name                                | batch | applied_at                 |\n+----+-------------------------------------+-------+----------------------------+\n|  1 | 19700101_0001_create_posts_table    |     1 | 2020-06-27 00:00:00.000000 |\n|  2 | 19700101_0002_create_comments_table |     1 | 2020-06-27 00:00:00.000000 |\n|  3 | 19700101_0003_rename_foreign_key    |     1 | 2020-06-27 00:00:00.000000 |\n+----+-------------------------------------+-------+----------------------------+\n```\n\nIf you want to use another name for migration table, change it `Migrator` before running migrations:\n\n```go\nm := migrator.Migrator{TableName: \"_my_app_migrations\"}\n```\n\n### Transactional migration\n\nIn case you have multiple commands within one migration and you want to be sure it is migrated properly, you might enable transactional execution per migration:\n\n```go\nvar migration = migrator.Migration{\n\tName: \"19700101_0001_create_posts_and_users_tables\",\n\tUp: func() migrator.Schema {\n\t\tvar s migrator.Schema\n\t\tposts := migrator.Table{Name: \"posts\"}\n\t\tposts.UniqueID(\"id\")\n\t\tposts.Timestamps()\n\n\t\tusers := migrator.Table{Name: \"users\"}\n\t\tusers.UniqueID(\"id\")\n\t\tusers.Timestamps()\n\n\t\ts.CreateTable(posts)\n\t\ts.CreateTable(users)\n\n\t\treturn s\n\t},\n\tDown: func() migrator.Schema {\n\t\tvar s migrator.Schema\n\n\t\ts.DropTableIfExists(\"users\")\n\t\ts.DropTableIfExists(\"posts\")\n\n\t\treturn s\n\t},\n\tTransaction: true,\n}\n```\n\n### Rollback and revert\n\nIn case you need to revert your deploy and DB, you can revert last migrated batch:\n\n```go\nm := migrator.Migrator{Pool: migrations}\nreverted, err := m.Rollback(db)\n\nif err != nil {\n\tlog.Errorf(\"Could not roll back migrations: %v\", err)\n\tos.Exit(1)\n}\n\nif len(reverted) == 0 {\n\tlog.Print(\"Nothing were rolled back.\")\n}\n\nfor _, m := range reverted {\n\tlog.Printf(\"Migration: %s was rolled back ✅\", m)\n}\n```\n\nTo revert all migrated items back, you have to call `Revert()` on your `migrator`:\n\n```go\nm := migrator.Migrator{Pool: migrations}\nreverted, err := m.Revert(db)\n```\n\n## Customize queries\n\nYou may add any column definition to the database on your own, just be sure you implement `columnType` interface:\n\n```go\ntype customType string\n\nfunc (ct customType) buildRow() string {\n\treturn string(ct)\n}\n\nposts := migrator.Table{Name: \"posts\"}\nposts.UniqueID(\"id\")\nposts.Column(\"data\", customType(\"json not null\"))\nposts.Timestamps()\n```\n\nThe same logic is for adding custom commands to the Schema to be migrated or reverted, just be sure you implement `command` interface:\n\n```go\ntype customCommand string\n\nfunc (cc customCommand) toSQL() string {\n\treturn string(cc)\n}\n\nvar s migrator.Schema\n\nc := customCommand(\"DROP PROCEDURE abc\")\ns.CustomCommand(c)\n```\n","funding_links":[],"categories":["Database","Uncategorized","Data Integration Frameworks","数据库","Generators"],"sub_categories":["Database Schema Migration","数据库模式迁移","Advanced Console UIs"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flarapulse%2Fmigrator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flarapulse%2Fmigrator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flarapulse%2Fmigrator/lists"}