Skip to content

Instantly share code, notes, and snippets.

@tucnak
Created May 21, 2020 19:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tucnak/fd407a7332ad49c496036cbe8d16674e to your computer and use it in GitHub Desktop.
Save tucnak/fd407a7332ad49c496036cbe8d16674e to your computer and use it in GitHub Desktop.
Automatic model migration for Postgres
func migrate(db *pg.DB, tables ...[]T) chan error {
errfeed := make(chan error)
go func() {
for _, model := range tables {
err := db.CreateTable(model, &orm.CreateTableOptions{IfNotExists: true})
if err != nil {
errfeed <- err
continue
}
table := orm.GetTable(reflect.TypeOf(model).Elem())
columns := make([]string, 0, len(table.Fields))
for _, field := range table.Fields {
columns = append(columns, `"`+field.SQLName+`" `+field.SQLType)
}
err = db.RunInTransaction(func(tx *pg.Tx) error {
for i, column := range columns {
query := fmt.Sprintf("ALTER TABLE %s ADD COLUMN IF NOT EXISTS %s",
table.Name, column)
defaultExpr := table.Fields[i].Default
if defaultExpr != "" {
query += " DEFAULT (" + string(defaultExpr) + ")"
}
if pgTag, ok := table.Fields[i].Field.Tag.Lookup("pg"); ok {
if strings.Contains(pgTag, "notnull") {
query += " NOT NULL"
}
}
_, err := tx.Exec(query)
if err != nil {
fmt.Println(query)
errfeed <- err
continue
}
}
return nil
})
if err != nil {
errfeed <- err
}
}
close(errfeed)
}()
return errfeed
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment