📚 dynago - Awesome Go Library for Database
Simplify working with AWS DynamoDB.
🏷️ Database
📂 Data stores with expiring records, in-memory distributed data stores, or in-memory subsets of file-based databases.
⭐ 12 stars
Detailed Description of dynago
Dynago
The aim of this package is to make it easier to work with AWS DynamoDB.
Documentation
For full documentation see pkg.go.dev.
Usage
Basic
package main
import (
"fmt"
"os"
"time"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/twharmon/dynago"
)
type Schema struct {}
func (s *Schema) PrimaryKeys() []string {
return []string{"PK", "SK"}
}
type Post struct {
// Embed a struct that implements the dynago.Keyer interface.
*Schema
// Set attribute name with `attr` tag if it needs to be different
// than field name. Use `fmt:"Post#{}"` to indicate how the value
// will be stored in DynamoDB.
ID string `attr:"PK" fmt:"Post#{}"`
Created time.Time `attr:"SK" fmt:"Created#{}"`
AuthorID string
Title string
Body string
}
func main() {
// Get client.
ddb := dynago.New(getDynamoDB(), &dynago.Config{
DefaultTableName: "tmp",
})
// Put item in DynamoDB.
p := Post{
ID: "hello-world",
Title: "Hi",
Body: "Hello world!",
Created: time.Now(),
}
if err := ddb.PutItem(&p).Exec(); err != nil {
panic(err)
}
// Get same item from DynamoDB. Fields used in the primary key
// must be set.
p2 := Post{
ID: p.ID,
Created: p.Created,
}
if err := ddb.GetItem(&p2).Exec(); err != nil {
panic(err)
}
fmt.Println(p2)
}
func getDynamoDB() *dynamodb.DynamoDB {
os.Setenv("AWS_SDK_LOAD_CONFIG", "true")
sess, err := session.NewSession()
if err != nil {
panic(err)
}
return dynamodb.New(sess)
}
Additional Attributes
package main
import (
"fmt"
"os"
"reflect"
"time"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/twharmon/dynago"
)
type Schema struct {}
func (s *Schema) PrimaryKeys() []string {
return []string{"PK", "SK"}
}
type Post struct {
// Embed a struct that implements the dynago.Keyer interface.
*Schema
ID string `attr:"PK" fmt:"Post#{}"`
AuthorID string
Title string
Body string
Created time.Time `attr:"SK" fmt:"Created#{}"`
}
type Author struct {
ID string `attr:"PK" fmt:"Author#{}"`
// Copy same value to attribute AltName by using `copy:"AltName"` in tag.
Name string `copy:"AltName"`
}
func main() {
// Get client.
ddb := dynago.New(getDynamoDB(), &dynago.Config{
DefaultTableName: "tmp",
AdditionalAttrs: additionalAttrs,
})
// ...
}
func additionalAttrs(item map[string]*dynamodb.AttributeValue, v reflect.Value) {
ty := v.Type().Name()
// Add a "Type" attribute to every item
item["Type"] = &dynamodb.AttributeValue{S: &ty}
// Add additional attributes for specific types
switch val := v.Interface().(type) {
case Author:
// Add a fat partition or sparse global secondary index to
// make querying for all authors possible
author := fmt.Sprintf("Author#%s", val.ID)
item["GSIPK"] = &dynamodb.AttributeValue{S: &ty}
item["GSISK"] = &dynamodb.AttributeValue{S: &author}
}
}
Compound Field Attributes
type Event struct {
Org string `attr:"PK" fmt:"Org#{}"`
// In this `fmt` tag, {} is equivalent to {Country}. You can
// reference a different field name by putting it's name in
// curly brackets.
Country string `attr:"SK" fmt:"Country#{}#City#{City}"`
// Since the City is specified in the "SK" attribute, we can
// skip putting it in another attribute if we want.
City string `attr:"-"`
Created time.Time
}
Contribute
Make a pull request.