expressive DynamoDB library for Go
Go
Switch branches/tags
Nothing to show
Clone or download
guregu Merge pull request #69 from SAPessi/master
removed ctx requirement from AllWithLastEvaluatedKey method
Latest commit e38c48c Mar 31, 2018
Permalink
Failed to load latest commit information.
internal/exprs go lint fixes Dec 10, 2015
.gitignore added gitignore Aug 3, 2015
LICENSE update license Nov 22, 2015
README.md tweak readme Aug 19, 2017
batch_test.go support measuring ConsumedCapacity Feb 4, 2018
batchget.go fix batch get returning duplicates when keys were missing #67 Mar 18, 2018
batchwrite.go support measuring ConsumedCapacity Feb 4, 2018
bench_test.go more benchmarks Dec 3, 2015
createtable.go add CreateTable.Index, allow multiple index strug tags Sep 16, 2017
createtable_test.go remove unfinished test Mar 16, 2016
db.go paging stuff: add LastEvaluatedKey, StartFrom Feb 4, 2018
db_test.go add DB.ListTables Aug 20, 2017
decode.go more helpful error messages on decode type mismatch Mar 16, 2018
decode_test.go improve handling of NULL-type values Mar 16, 2018
delete.go support measuring ConsumedCapacity Feb 4, 2018
delete_test.go support measuring ConsumedCapacity Feb 4, 2018
describetable.go fix panic when describing tables with deleting indexes Aug 20, 2017
describetable_test.go implement DescribeTable Aug 19, 2017
encode.go don't clobber fields when embedding structs Jan 31, 2018
encode_test.go remove temp test dep Aug 19, 2017
encoding_aws.go compatibility with the official dynamodbattribute package Jun 8, 2017
encoding_aws_test.go fix flaky test? Jun 8, 2017
encoding_test.go the tiniest of test tweaks Jan 31, 2018
keys.go support for creating and deleting GSI in UpdateTable Aug 19, 2017
put.go support measuring ConsumedCapacity Feb 4, 2018
put_test.go support measuring ConsumedCapacity Feb 4, 2018
query.go support measuring ConsumedCapacity Feb 4, 2018
query_test.go support measuring ConsumedCapacity Feb 4, 2018
reserved.go reserved words Mar 3, 2015
retry.go add a blurb about how RetryTimeout is only for non-ctx methods Jun 7, 2017
scan.go removed ctx requirement from AllWithLastEvaluatedKey method Mar 30, 2018
scan_test.go support measuring ConsumedCapacity Feb 4, 2018
substitute.go experimental support for TextMarshaler map keys Oct 16, 2017
substitute_test.go update Update, misc clean up Dec 4, 2015
table.go support measuring ConsumedCapacity Feb 4, 2018
update.go support measuring ConsumedCapacity Feb 4, 2018
update_test.go support measuring ConsumedCapacity Feb 4, 2018
updatetable.go add CreateTable.Index, allow multiple index strug tags Sep 16, 2017
updatetable_test.go minor fixes Aug 19, 2017

README.md

dynamo GoDoc Circle CI

import "github.com/guregu/dynamo"

dynamo is an expressive DynamoDB client for Go, with an API heavily inspired by mgo. dynamo integrates with the official AWS SDK.

dynamo is still under development, so the API may change rarely. However, breaking changes will be avoided and the API can be considered relatively stable.

Example

package dynamo

import (
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/guregu/dynamo"
)

// Use struct tags much like the standard JSON library,
// you can embed anonymous structs too!
type widget struct {
	UserID int       // Hash key, a.k.a. partition key
	Time   time.Time // Range key, a.k.a. sort key

	Msg       string              `dynamo:"Message"`
	Count     int                 `dynamo:",omitempty"`
	Friends   []string            `dynamo:",set"` // Sets
	Set       map[string]struct{} `dynamo:",set"` // Map sets, too!
	SecretKey string              `dynamo:"-"`    // Ignored
	Children  []any               // Lists
}


func main() {
	db := dynamo.New(session.New(), &aws.Config{Region: aws.String("us-west-2")})
	table := db.Table("Widgets")
	
	// put item
	w := widget{UserID: 613, Time: time.Now(), Msg: "hello"}
	err := table.Put(w).Run() 
	
	// get the same item 
	var result widget
	err = table.Get("UserID", w.UserID).
		Range("Time", dynamo.Equal, w.Time).
		Filter("'Count' = ? AND $ = ?", w.Count, "Message", w.Msg). // placeholders in expressions
		One(&result)
	
	// get all items
	var results []widget
	err = table.Scan().All(&results)
}

Expressions

dynamo will help you write expressions used to filter results in queries and scans, and add conditions to puts and deletes.

Attribute names may be written as is if it is not a reserved word, or be escaped with single quotes (''). You may also use dollar signs ($) as placeholders for attribute names. DynamoDB has very large amount of reserved words so it may be a good idea to just escape everything.

Question marks (?) are used as placeholders for attribute values. DynamoDB doesn't have value literals, so you need to substitute everything.

Please see the DynamoDB reference on expressions for more information.

// Using single quotes to escape a reserved word, and a question mark as a value placeholder.
// Finds all items whose date is greater than or equal to lastUpdate.
table.Scan().Filter("'Date' >= ?", lastUpdate).All(&results)

// Using dollar signs as a placeholder for attribute names. 
// Deletes the item with an ID of 42 if its score is at or below the cutoff, and its name starts with G.
table.Delete("ID", 42).If("Score <= ? AND begins_with($, ?)", cutoff, "Name", "G").Run()

// Put a new item, only if it doesn't already exist.
table.Put(item{ID: 42}).If("attribute_not_exists(ID)").Run()

Encoding support

dynamo automatically handles the following interfaces:

This allows you to define custom encodings and provides built-in support for types such as time.Time.

Compatibility with the official AWS library

dynamo has been in development before the official AWS libraries were stable. We use a different encoder and decoder than the dynamodbattribute package. dynamo uses the dynamo struct tag instead of the dynamodbav struct tag, and we also prefer to automatically omit invalid values such as empty strings, whereas the dynamodbattribute package substitutes null values for them. Items that satisfy the dynamodbattribute.(Un)marshaler interfaces are compatibile with both libraries.

In order to use dynamodbattribute's encoding facilities, you must wrap objects passed to dynamo with dynamo.AWSEncoding. Here is a quick example:

// Notice the use of the dynamodbav struct tag
type book struct {
	ID    int    `dynamodbav:"id"`
	Title string `dynamodbav:"title"`
}
// Putting an item
err := db.Table("Books").Put(dynamo.AWSEncoding(book{
	ID:    42,
	Title: "Principia Discordia",
})).Run()
// When getting an item you MUST pass a pointer to AWSEncoding!
var someBook book
err := db.Table("Books").Get("ID", 555).One(dynamo.AWSEncoding(&someBook))

Integration tests

By default, tests are run in offline mode. Create a table called TestDB, with a Number Parition Key called UserID and a String Sort Key called Time. Change the table name with the environment variable DYNAMO_TEST_TABLE. You must specify DYNAMO_TEST_REGION, setting it to the AWS region where your test table is.

DYNAMO_TEST_REGION=us-west-2 go test github.com/guregu/dynamo/... -cover

License

BSD