メメメモモ

プログラミング、リモートワーク生活、筋トレ、etc

DynamoDBlocalでDynamoDBをひとまず触れるようにする

f:id:memememomo:20180812135649p:plain

概要

DynamoDBはAWSのマネージドサービスの一つです。
DynamoDBは、開発のために手元のPCで動作させることができます。
本記事では、以下の方法をご紹介します。

  • DynamoDBLocalを手元のPCに入れる
  • aws-cliでDynamoDBを操作する
  • Go言語でDynamoDBを操作する

DynamoDBLocalを手元のPCに入れる

以下のURLから、DynamoDBLocalをダウンロードします。 https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/DynamoDBLocal.html

アーカイブを解凍したら、以下のコマンドでDynamoDBローカルを立ち上げます。

$ java -Djava.library.path=./DynamoDBLocal_lib -jar DynamoDBLocal.jar -sharedDb

http://localhost:8000/shell/にアクセスするとJavascriptで操作することもできます。

aws-cliで操作する

aws-cliで操作するときのポイントは、以下のとおりです。

  • --endpoint-urlhttp://localhost:8000を指定する
  • ローカルでも--profileまたはAWS_PROFILEの設定が必要となる

テーブルを作成する

$ aws dynamodb create-table --table-name Persons \
   --attribute-definitions AttributeName=Id,AttributeType=N \
  --key-schema AttributeName=Id,KeyType=HASH \
  --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1 \
  --endpoint-url http://localhost:8000

テーブル一覧を表示する

$ aws dynamodb list-tables --endpoint-url http://localhost:8000

テーブルにデータを挿入する

$ aws dynamodb put-item --table-name Persons --item '{"Id":{"N":"1"},"Name":{"S":"Jack"}}' --endpoint-url http://localhost:8000

データを取得する

$ aws dynamodb get-item --table-name Persons --key '{"Id":{"N":"1"}}' --endpoint-url http://localhost:8000

データをスキャンする

$ aws dynamodb scan --table-name Persons --endpoint-url http://localhost:8000

Go言語で操作する

ダミーのCredentialsを用意しておく

ローカルなDynamoDBに接続する際もCredentialを設定する必要があるので、以下のようにダミーを設定しておきます。

# ~/.aws/credentials
[dummy]
aws_access_key_id = dummy
aws_secret_access_key = dummy

SDKの導入

go get -u github.com/aws/aws-sdk-go

ひとまず参照するコード

aws-cliで作成したPersonsテーブルからデータを取得するコードです。

// main.go
package main

import (
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/service/dynamodb"
    "fmt"
    "github.com/aws/aws-sdk-go/aws/credentials"
)

func main() {
    dynamoSession, err := session.NewSession(&aws.Config{
        Region: aws.String("ap-northeast-1"),
        Endpoint: aws.String("http://localhost:8000"),
        Credentials: credentials.NewStaticCredentials("dummy", "dummy", "dummy"),
    })
    if err != nil {
        panic(err)
    }

    db := dynamodb.New(dynamoSession)

    res, err := db.GetItem(&dynamodb.GetItemInput{
        TableName: aws.String("Persons"),
        Key: map[string]*dynamodb.AttributeValue{
            "Id": {
                N: aws.String("1"),
            },
        },
        AttributesToGet: []*string{
            aws.String("Name"),
        },
        ConsistentRead: aws.Bool(true),
        ReturnConsumedCapacity: aws.String("NONE"),
    })

    if err != nil {
        panic(err)
    }

    fmt.Println(*res.Item["Name"])
}

guregu/dynamoを使用する

https://github.com/guregu/dynamo

ORMのようなものです。 jsonモジュールのように、構造体にマッピングしてくれます。

$ go get github.com/guregu/dynamo
// main.go
package main

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

type Person struct {
    ID int `dynamo:"Id"`
    Name string `dynamo:"Name"`
}

func main() {
    dynamoSession, err := session.NewSession(&aws.Config{
        Region: aws.String("ap-northeast-1"),
        Endpoint: aws.String("http://localhost:8000"),
        Credentials: credentials.NewStaticCredentials("dummy", "dummy", "dummy"),
    })
    if err != nil {
        panic(err)
    }

    db := dynamo.New(dynamoSession)
    table := db.Table("Persons")

    var ret Person
    err = table.Get("Id", 1).One(&ret)
    if err != nil {
        panic(err)
    }

    println(ret.Name)
}

ライセンス