Skip to content
No description, website, or topics provided.
Branch: master
Clone or download
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
testdata tests WIP May 25, 2017
vendor/github.com fix missing errors from callbacks and actions, +tests Jun 1, 2017
Gopkg.lock
Gopkg.toml deps via dep May 30, 2017
LICENSE initial WIP May 24, 2017
README.md circle badge May 30, 2017
circle.yml fix dynamo paging bug, +test, +automatically start dynamodblocal for … Jun 1, 2017
drift.go
drift_test.go fix for RawDynamoItem inserts + test Jun 2, 2017

README.md

dynamo-drift

Go Documentation

CircleCI

dynamo-drift is a minimalistic library for performing DynamoDB schema migrations.

Individual migrations are code that is executed in the context of a callback performed per existing table item. You can execute actions within callbacks (update/insert/delete) which are deferred until after all callbacks complete, or use the DynamoDB client directly for immediate table operations. Migrations and actions can modify any table, not just the target table of the migration (this allows a migration from one table into another, for example).

dynamo-drift:

  • keeps track of migrations already executed via a separate configurable metadata table
  • executes the supplied migrations, each with the requested concurrency
  • queues and executes actions (insert/update/delete) after callbacks finish so that they do not interfere with the main table scan

It is the responsibility of the application to determine:

  • what a migration consists of and when it may be executed
  • when to rollback or undo a migration, and what that means
  • how many active migrations exist at any given time

Example

import (
  "github.com/aws/aws-sdk-go/aws/session"
  "github.com/aws/aws-sdk-go/service/dynamodb"
  "github.com/dollarshaveclub/dynamo-drift"
)

func main() {
  // get authenticated DynamoDB client
  client := dynamodb.New(session.Must(session.NewSession()))

  // create migrator
  dd := drift.DynamoDrifter{}
  dd.MetaTableName = "MyMigrationsTable"
  dd.DynamoDB = client

  // initialize
  dd.Init(10, 10)

  // check applied
  migrations, _ := dd.Applied()
  fmt.Printf("migrations already applied: %v\n", len(migrations)) // "migrations already applied: 0"

  // create migration
  migration := &drift.DynamoDrifterMigration{
    Number: 0,
    TableName: "MyApplicationTable",
    Description: "readme test",
    Callback: migrateUp,
  }

  // run migration
  errs := dd.Run(context.TODO(), migration, 1, true)
  for _, err := range errs {
    fmt.Printf("error during up migration: %v", err)
  }

  migrations, _ = dd.Applied()
  fmt.Printf("migrations already applied: %v\n", len(migrations)) // "migrations already applied: 1"

  migration.Callback = migrateDown

  // run undo migration
  errs := dd.Undo(context.TODO(), migration, 1, true)
  for _, err := range errs {
    fmt.Printf("error during down migration: %v", err)
  }

  migrations, _ = dd.Applied()
  fmt.Printf("migrations already applied: %v\n", len(migrations)) // "migrations already applied: 0"
}

// Callbacks are executed once for each item in the target table
func migrateUp(item drift.RawDynamoItem, action *drift.DrifterAction) {
  // modify this table item somehow
}

func migrateDown(item drift.RawDynamoItem, action *drift.DrifterAction) {
  // do something to undo migration
}
You can’t perform that action at this time.