Skip to content

Instantly share code, notes, and snippets.

@daneharrigan
Created August 31, 2013 02:44
Show Gist options
  • Save daneharrigan/6395929 to your computer and use it in GitHub Desktop.
Save daneharrigan/6395929 to your computer and use it in GitHub Desktop.
The official AWS process for exporting a DynamoDB table is overly complex. These two scripts make exporting and importing much easier.
package main
import (
"bytes"
"flag"
"fmt"
"github.com/bmizerany/aws4"
"io/ioutil"
"log"
"net/http"
"time"
)
var (
t = flag.String("t", "", "Table Name")
k = flag.String("k", "", "AWS Key")
s = flag.String("s", "", "AWS Secret")
keys *aws4.Keys
svc *aws4.Service
)
// Usage: go run export.go -k [AWS-KEY] -s [AWS-SECRET] -t [TABLE-NAME] > table.json
//
// Exports a DynamoDB table into a JSON file
func init() {
flag.Parse()
keys = &aws4.Keys{
AccessKey: *k,
SecretKey: *s,
}
svc = &aws4.Service{
Name: "dynamodb",
Region: "us-east-1",
}
}
func main() {
q := fmt.Sprintf(`{ "TableName": %q }`, *t)
buf := bytes.NewReader([]byte(q))
url := "https://dynamodb.us-east-1.amazonaws.com/"
req, _ := http.NewRequest("POST", url, buf)
req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
req.Header.Set("X-Amz-Target", "DynamoDB_20111205.Scan")
req.Header.Set("Content-Type", "application/x-amz-json-1.0")
err := svc.Sign(keys, req)
if err != nil {
log.Fatalf("fn=Sign error=%q", err)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatalf("fn=Do error=%q", err)
}
defer res.Body.Close()
payload, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatalf("fn=ReadAll error=%q", err)
}
fmt.Printf("%s", payload)
}
package main
import (
"bytes"
"encoding/json"
"flag"
"github.com/bmizerany/aws4"
"io/ioutil"
"log"
"net/http"
"time"
)
var (
f = flag.String("f", "", "File Path")
t = flag.String("t", "", "Table Name")
k = flag.String("k", "", "AWS Key")
s = flag.String("s", "", "AWS Secret")
keys *aws4.Keys
svc *aws4.Service
)
// Usage: go run import.go -k [AWS-KEY] -s [AWS-SECRET] -t [TABLE-NAME] -f [FILE-NAME]
//
// Imports a JSON file into an existing DynamoDB table
func init() {
flag.Parse()
keys = &aws4.Keys{
AccessKey: *k,
SecretKey: *s,
}
svc = &aws4.Service{
Name: "dynamodb",
Region: "us-east-1",
}
}
func main() {
b, err := ioutil.ReadFile(*f)
if err != nil {
log.Fatalf("fn=ReadFile error=%q", err)
}
var d struct {
Items []map[string]map[string]string
}
err = json.Unmarshal(b, &d)
if err != nil {
log.Fatalf("fn=Unmarshal error=%q", err)
}
for _, i := range d.Items {
var q struct {
TableName string
Item map[string]map[string]string
}
q.TableName = *t
q.Item = i
payload, err := json.Marshal(q)
if err != nil {
log.Fatalf("fn=Marshal error=%q", err)
}
log.Printf("at=import table=%s bytes=%d", *t, len(payload))
buf := bytes.NewReader(payload)
url := "https://dynamodb.us-east-1.amazonaws.com/"
req, _ := http.NewRequest("POST", url, buf)
req.Header.Set("Date", time.Now().UTC().Format(http.TimeFormat))
req.Header.Set("X-Amz-Target", "DynamoDB_20120810.PutItem")
req.Header.Set("Content-Type", "application/x-amz-json-1.0")
err = svc.Sign(keys, req)
if err != nil {
log.Fatalf("fn=Sign error=%q", err)
}
res, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatalf("fn=Do error=%q", err)
}
if res.StatusCode != 200 {
msg, _ := ioutil.ReadAll(res.Body)
log.Printf("at=response error=%q", res.Status, msg)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment