Skip to content

Commit

Permalink
Add --skip-validation flag to start command (#448)
Browse files Browse the repository at this point in the history
Add a `--skip-validation` flag to the `start` command.

If set, migration validation is skipped.

For example, this table has a `NOT NULL` `name` field:

```json
{
  "name": "01_create_table",
  "operations": [
    {
      "create_table": {
        "name": "products",
        "columns": [
          {
            "name": "id",
            "type": "serial",
            "pk": true
          },
          {
            "name": "name",
            "type": "varchar(255)",
            "nullable": false
          }
        ]
      }
    }
  ]
}
```

starting this migration will fail as the `name` field is already `NOT
NULL`:

```json
{
  "name": "02_set_nullable",
  "operations": [
    {
      "alter_column": {
        "table": "products",
        "column": "name",
        "nullable": false,
        "up": "name",
        "down": "name"
      }
    }
  ]
}
```

```
Error: migration is invalid: column "name" on table "products" is NOT NULL
```

But if the start command is invoked with `--skip-validation` then the
start command succeeds.

This is part of #239
  • Loading branch information
andrew-farries authored Nov 6, 2024
1 parent eef4a9b commit 0992c8d
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 5 deletions.
2 changes: 2 additions & 0 deletions cmd/flags/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ func BackfillBatchSize() int { return viper.GetInt("BACKFILL_BATCH_SIZE") }

func BackfillBatchDelay() time.Duration { return viper.GetDuration("BACKFILL_BATCH_DELAY") }

func SkipValidation() bool { return viper.GetBool("SKIP_VALIDATION") }

func Role() string {
return viper.GetString("ROLE")
}
2 changes: 2 additions & 0 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func NewRoll(ctx context.Context) (*roll.Roll, error) {
role := flags.Role()
backfillBatchSize := flags.BackfillBatchSize()
backfillBatchDelay := flags.BackfillBatchDelay()
skipValidation := flags.SkipValidation()

state, err := state.New(ctx, pgURL, stateSchema)
if err != nil {
Expand All @@ -62,6 +63,7 @@ func NewRoll(ctx context.Context) (*roll.Roll, error) {
roll.WithRole(role),
roll.WithBackfillBatchSize(backfillBatchSize),
roll.WithBackfillBatchDelay(backfillBatchDelay),
roll.WithSkipValidation(skipValidation),
)
}

Expand Down
4 changes: 4 additions & 0 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (

"github.com/pterm/pterm"
"github.com/spf13/cobra"
"github.com/spf13/viper"

"github.com/xataio/pgroll/cmd/flags"
"github.com/xataio/pgroll/pkg/migrations"
Expand Down Expand Up @@ -39,6 +40,9 @@ func startCmd() *cobra.Command {

startCmd.Flags().BoolVarP(&complete, "complete", "c", false, "Mark the migration as complete")

startCmd.Flags().BoolP("skip-validation", "s", false, "skip migration validation")
viper.BindPFlag("SKIP_VALIDATION", startCmd.Flags().Lookup("skip-validation"))

return startCmd
}

Expand Down
12 changes: 7 additions & 5 deletions pkg/roll/execute.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ func (m *Roll) StartDDLOperations(ctx context.Context, migration *migrations.Mig
}

// validate migration
err = migration.Validate(ctx, newSchema)
if err != nil {
if err := m.state.Rollback(ctx, m.schema, migration.Name); err != nil {
fmt.Printf("failed to rollback migration: %s\n", err)
if !m.skipValidation {
err = migration.Validate(ctx, newSchema)
if err != nil {
if err := m.state.Rollback(ctx, m.schema, migration.Name); err != nil {
fmt.Printf("failed to rollback migration: %s\n", err)
}
return nil, fmt.Errorf("migration is invalid: %w", err)
}
return nil, fmt.Errorf("migration is invalid: %w", err)
}

// run any BeforeStartDDL hooks
Expand Down
11 changes: 11 additions & 0 deletions pkg/roll/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ type options struct {
// the duration to delay after each batch is run
backfillBatchDelay time.Duration

// whether to skip validation
skipValidation bool

migrationHooks MigrationHooks
}

Expand Down Expand Up @@ -121,3 +124,11 @@ func WithBackfillBatchDelay(delay time.Duration) Option {
o.backfillBatchDelay = delay
}
}

// WithSkipValidation controls whether or not to perform validation on
// migrations. If set to true, validation will be skipped.
func WithSkipValidation(skip bool) Option {
return func(o *options) {
o.skipValidation = skip
}
}
2 changes: 2 additions & 0 deletions pkg/roll/roll.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ type Roll struct {

backfillBatchSize int
backfillBatchDelay time.Duration
skipValidation bool
}

// New creates a new Roll instance
Expand Down Expand Up @@ -84,6 +85,7 @@ func New(ctx context.Context, pgURL, schema string, state *state.State, opts ...
migrationHooks: rollOpts.migrationHooks,
backfillBatchSize: rollOpts.backfillBatchSize,
backfillBatchDelay: rollOpts.backfillBatchDelay,
skipValidation: rollOpts.skipValidation,
}, nil
}

Expand Down

0 comments on commit 0992c8d

Please sign in to comment.