Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Minimalistic database migration helper for Gorm ORM

License

NotificationsYou must be signed in to change notification settings

go-gormigrate/gormigrate

Repository files navigation

Latest ReleaseGo ReferenceGo Report CardCI | LintCI | Test

Gormigrate is a minimalistic migration helper forGorm.Gorm already has usefulmigrate functions, just missesproper schema versioning and migration rollback support.

IMPORTANT: If you need support to Gorm v1 (which usesgithub.com/jinzhu/gorm as its import path), please import Gormigrate byusing thegopkg.in/gormigrate.v1 import path.

The current Gorm version (v2) is supported by using thegithub.com/go-gormigrate/gormigrate/v2 import path as described in thedocumentation below.

Supported databases

It supports any of thedatabases Gorm supports:

  • MySQL
  • MariaDB
  • PostgreSQL
  • SQLite
  • Microsoft SQL Server
  • TiDB
  • Clickhouse

Usage

package mainimport ("log""github.com/go-gormigrate/gormigrate/v2""github.com/google/uuid""gorm.io/driver/sqlite""gorm.io/gorm""gorm.io/gorm/logger")funcmain() {db,err:=gorm.Open(sqlite.Open("./data.db"),&gorm.Config{Logger:logger.Default.LogMode(logger.Info),})iferr!=nil {log.Fatal(err)}m:=gormigrate.New(db,gormigrate.DefaultOptions, []*gormigrate.Migration{{// create `users` tableID:"201608301400",Migrate:func(tx*gorm.DB)error {// it's a good pratice to copy the struct inside the function,// so side effects are prevented if the original struct changes during the timetypeuserstruct {ID   uuid.UUID`gorm:"type:uuid;primaryKey;uniqueIndex"`Namestring}returntx.Migrator().CreateTable(&user{})},Rollback:func(tx*gorm.DB)error {returntx.Migrator().DropTable("users")},}, {// add `age` column to `users` tableID:"201608301415",Migrate:func(tx*gorm.DB)error {// when table already exists, define only columns that are about to changetypeuserstruct {Ageint}returntx.Migrator().AddColumn(&user{},"Age")},Rollback:func(tx*gorm.DB)error {typeuserstruct {Ageint}returndb.Migrator().DropColumn(&user{},"Age")},}, {// create `organizations` table where users belong toID:"201608301430",Migrate:func(tx*gorm.DB)error {typeorganizationstruct {ID      uuid.UUID`gorm:"type:uuid;primaryKey;uniqueIndex"`NamestringAddressstring}iferr:=tx.Migrator().CreateTable(&organization{});err!=nil {returnerr}typeuserstruct {OrganizationID uuid.UUID`gorm:"type:uuid"`}returntx.Migrator().AddColumn(&user{},"OrganizationID")},Rollback:func(tx*gorm.DB)error {typeuserstruct {OrganizationID uuid.UUID`gorm:"type:uuid"`}iferr:=db.Migrator().DropColumn(&user{},"OrganizationID");err!=nil {returnerr}returntx.Migrator().DropTable("organizations")},}})iferr:=m.Migrate();err!=nil {log.Fatalf("Migration failed: %v",err)}log.Println("Migration did run successfully")}

Having a separate function for initializing the schema

If you have a lot of migrations, it can be a pain to run all them, as example,when you are deploying a new instance of the app, in a clean database.To prevent this, you can set a function that will run if no migration was runbefore (in a new clean database). Remember to create everything here, all tables,foreign keys and what more you need in your app.

typeOrganizationstruct {gorm.ModelNamestringAddressstring}typeUserstruct {gorm.ModelNamestringAgeintOrganizationIDuint}m:=gormigrate.New(db,gormigrate.DefaultOptions, []*gormigrate.Migration{// your migrations here})m.InitSchema(func(tx*gorm.DB)error {err:=tx.AutoMigrate(&Organization{},&User{},// all other tables of you app)iferr!=nil {returnerr}iferr:=tx.Exec("ALTER TABLE users ADD CONSTRAINT fk_users_organizations FOREIGN KEY (organization_id) REFERENCES organizations (id)").Error;err!=nil {returnerr}// all other constraints, indexes, etc...returnnil})

Options

This is the options struct, in case you don't want the defaults:

typeOptionsstruct {// TableName is the migration table.TableNamestring// IDColumnName is the name of column where the migration id will be stored.IDColumnNamestring// IDColumnSize is the length of the migration id columnIDColumnSizeint// UseTransaction makes Gormigrate execute migrations inside a single transaction.// Keep in mind that not all databases support DDL commands inside transactions.UseTransactionbool// ValidateUnknownMigrations will cause migrate to fail if there's unknown migration// IDs in the databaseValidateUnknownMigrationsbool}

Who is Gormigrate for?

Gormigrate was born to be a simple and minimalistic migration tool for smallprojects that usesGorm. You may want to take a look at more advancedsolutions likegolang-migrate/migrateif you plan to scale.

Be aware that Gormigrate has no builtin lock mechanism, so if you're runningit automatically and have a distributed setup (i.e. more than one executablerunning at the same time), you might want to use adistributed lock/mutex mechanism toprevent race conditions while running migrations.

Contributing

To run integration tests, some preparations are needed. Please ensure youhavetask anddocker installed.Then:

  1. Ensure target or all databases are available and ready to accept connections.You can start databases locally withtask docker:compose:up
  2. Copyintegration-test/.example.env asintegration-test/.env andadjust the database connection ports and credentials when needed.
  3. Run integration test for single database or for all
# run test for MySQLtask test:mysql# run test for MariaDBtask test:mariadb# run test for PostgreSQLtask test:postgres# run test for SQLitetask test:sqlite# run test for Microsoft SQL Servertask test:sqlserver# run test for all databasestask test:all

Alternatively, you can run everything in one step:task docker:test


[8]ページ先頭

©2009-2025 Movatter.jp