help wanted
Description
Hey folks,
I've been trying very hard to read the migration docs without success.
When I've tried to write go migrations to create the tables, they've not been particularly successful due to trying to reuse the Model for creating the initial table. There are a couple of problems I've faced.
- For local development:
- If I add the new field via the struct first then add the migration to add the column, a new fresh db migration breaks due to the fact that the new column already exists.
- If I only add the struct field, it would not be updated in existing setups. The same would hold true for only adding the migration that adds the column and not adding the struct field.
- using
bun:"-"always omits the struct field for both creation and querying
Any help with sorting out the below would be appreciated. I'd like to avoid having to iteratively build .sql migrations to handle these sorts of cases.
Here are the example migrations and struct:
model definition
package models
import (
"github.com/google/uuid"
"github.com/uptrace/bun"
)
type TestRun struct {
bun.BaseModel `json:"-"`
ID uuid.UUID `bun:"type:uuid,notnull"`
FileName string `bun:",nullzero,notnull"`
CreatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"`
UpdatedAt time.Time `bun:",nullzero,notnull,default:current_timestamp"`
// NewColumn map[string]interface{} `bun:"type:jsonb"` breaks this chain
}
migration 1
package migrations
import (
"context"
"fmt"
"github.com/uptrace/bun"
)
func init() {
Migrations.MustRegister(func(ctx context.Context, db *bun.DB) error {
_, err := db.NewCreateTable().IfNotExists().Model(&models.TestRun{}).Exec(ctx)
if err != nil {
return err
}
fmt.Print(" [up migration] ")
return nil
}, func(ctx context.Context, db *bun.DB) error {
_, err := db.NewDropTable().Model(&models.TestRun{}).Exec(ctx)
if err != nil {
return err
}
fmt.Print(" [down migration] ")
return nil
})
}
migration 2
package migrations
import (
"context"
"fmt"
"github.com/uptrace/bun"
)
func init() {
Migrations.MustRegister(func(ctx context.Context, db *bun.DB) error {
_, err := db.NewAddColumn().Table("test_runs").ColumnExpr("new_column jsonb NULL").Exec(ctx)
if err != nil {
return err
}
fmt.Print(" [up migration] ")
return nil
}, func(ctx context.Context, db *bun.DB) error {
_, err := db.NewDropColumn().Table("test_runs").ColumnExpr("new_column").Exec(ctx)
if err != nil {
return err
}
fmt.Print(" [down migration] ")
return nil
})
}