前提
最近、Go言語を触り始めた。
GoからDynamoDBに接続するにあたって、 aws-sdk-go/aws/service/dynamodb を使おうとし、ドキュメントを読んでたら結構難しそうだったので、 guregu/dynamo を使うことにした。
また、DynamoDBも触ったことがなかった。
ゴールは、GoでDynamoDBに読み書きすること!
DynamoDBの設定
まず、AWSコンソール画面からDynamoDBのテーブルを作ります。
上記の画面で、「テーブル名」を Test とします。
「プライマリーキー」を user_id とします。型は「数値」にします。
他のattributeにかんしては、時間に関する値を想定してますが、実際にGoからItemをPUTするときに足されるので、定義する必要はありません。(そもそも登録もできない。)
(キャメルケースがいいのか、パスカルケースがいいのか等の命名規則もあるかと思いますが、一旦これでいきます。)
これでAWS側の用意は出来ました。
あと、もう一つ大事なこととして
IAMで、DynamoDBにアクセスできる権限をもったユーザーを作成し、
- アクセスキー
 - シークレットキー
 
を入手しましょう。
Go言語をかく!
user_dynamo.goという名前でファイルを作成します。
必要なモジュール
以下のリアブラリをimportします。
import (
  "fmt"
  "time"
  "github.com/aws/aws-sdk-go/aws"
  "github.com/aws/aws-sdk-go/aws/session"
  "github.com/aws/aws-sdk-go/aws/credentials"
  "github.com/guregu/dynamo"
)
| ライブラリ名 | 説明 | 
|---|---|
| fmt | 標準出力に使う。 | 
| time | 現在時刻を取得するのに使う。 | 
| github.com/aws/aws-sdk-go/aws | configに関するオブジェクト作成につかう | 
| github.com/aws/aws-sdk-go/aws/session | sessionに関するオブジェクト作成につかう | 
| github.com/aws/aws-sdk-go/aws/credentials | awsへのアクセス情報に関するオブジェクト作成につかう | 
| github.com/guregu/dynamo | github.com/aws/aws-sdk-go/aws/service/dynamodbに対する操作を便利にしてくれるライブラリ | 
DynamoDBのスキーマ定義
この言い回しが正しいかわかりませんが、DynamoDBのUserテーブルに登録する予定の項目を構造体として定義します。
type User struct {
  UserId int `dynamo:"user_id"`
  CreatedTime time.Time `dynamo:"created_time"`
}
int や time.Time のあとのバッククウォートで囲まれた部分はGoで「タグ情報」と呼ばれるものになります。
DynamoDBのUserテーブルにアクセス
func main(){
  c := credentials.NewStaticCredentials("<アクセスキー>", "<シークレットキー>", "") // 最後の引数は[セッショントークン]
  db := dynamo.New(session.New(), &aws.Config{
      Credentials: c,
      Region: aws.String("<region名>"), // "ap-northeast-1"等
  })
  table := db.Table("Test")
 // 続く
}
のように書きます。
データをPUTする
func main(){
  // 続き
  u := User{UserId: 3, CreatedTime: time.Now().UTC()}
  fmt.Println(u)
  
  if err := table.Put(u).Run(); err != nil {
    fmt.Println("err")
    panic(err.Error())
  }
上記をまとめると
package main
import (
  "fmt"
  "time"
  "github.com/aws/aws-sdk-go/aws"
  "github.com/aws/aws-sdk-go/aws/session"
  "github.com/aws/aws-sdk-go/aws/credentials"
  "github.com/guregu/dynamo"
)
type User struct {
  UseId int `dynamo:"use_id"`
  CreatedTime time.Time `dynamo:"created_time"`
}
func main(){
  cred := credentials.NewStaticCredentials("<アクセスキー>", "<シークレットキー>", "") // 最後の引数は[セッショントークン]
  db := dynamo.New(session.New(), &aws.Config{
      Credentials: cred,
      Region: aws.String("<region名>"), // "ap-northeast-1"等
  })
  table := db.Table("User")
  u := User{UserId: 100, CreatedTime: time.Now().UTC()}
  fmt.Println(u)
  
  if err := table.Put(u).Run(); err != nil {
    fmt.Println("err")
    panic(err.Error())
  }
それではterminalから
$ go run user_dynamo.go
とうってみてください。DynamoDBに
| user_id | created_time | 
|---|---|
| 100 | 2017-06-02T09:25:56.000147134Z | 
と登録されたかと思います。これで、DynamoDBへのデータ登録は完了です。
データの読み取り
DynamoDBより
「user_idが100のデータ全て」
データを読み取る場合は以下のようになります。
func main(){
  // 続き
  var users []User
  err := table.Get("user_id", 100).All(&users)
  if err != nil {
    fmt.Println("err")
    panic(err.Error())
  }
  fmt.Println(users) // [{100 2017-06-02T09:25:56.000147134 +0000 UTC}]と出力される。
  for i, _ := range users {
    fmt.Println(users[i]) // {100 2017-06-02T09:25:56.000147134 +0000 UTC}
  }
}
また全データを取得したい場合は
err := table.Get("user_id", 1).All(&users)
というところを
err := table.Scan().All(&users)
とすれば大丈夫です。
さらに created_time によって、絞りたい場合は以下のようにすれば大丈夫です。
err := table.Get("user_id", 1).Filter("created_time >= ?", "2017-06-01 00:00:00").All(&users)
注意点
DynamoDBでは、プライマリーキーは、DBで一つしか存在できないので、本コードでは書き込みをするたびに書き換わります。
参考にしたサイト
http://www.geocities.jp/m_hiroi/golang/abcgo07.html
https://github.com/guregu/dynamo
http://qiita.com/guregu/items/2e9ac305791935b86f5d
https://developers.eure.jp/tech/aws-sdk-go-tutorial-sqs-dynamodb/
