Skip to Content

Fargateで動くSIM残容量をLINE通知システム DynamoDBから値の取得編

概要

DockerコンテナからDynamoDBへアクセスして最新値を取ってくる部分の説明
大本はFargateで動くSIM残容量をLINE通知システム 概要編

コード全文

github

DynamoDBのテーブル

LambdaでスクレイピングしてSIMの残量を保存しています
確認した日付(check_date)をキーに、残用容量(remainig_capacity)のシンプルなキーバリューのテーブルです

SQSのキュー

キューに入れられればそれで良かったので標準的なキュー設定です

DynamoDBから取り出し、SQSへ入れる

要所要所の解説

DynamoDBとのセッション

セッション を作成
資格情報は自端末では~/.aws/credentialsから取得し、
Fargateで実行する際はECSのタスクに割り当てたIAMロールの権限で実行することになります

1
2
3
4
5
	sess := session.Must(session.NewSession())
	svc := dynamodb.New(
		sess,
		aws.NewConfig().WithRegion(REGION),
	)

DynamoDBからデータ取得

検索キー

検索キーになるのはDynamoDBのパーティションキー
文字列の日付(YYYY-MM-DD)で登録されています
最新の値が欲しいので今日の日付を整形してkeyDayに入れます

2006年1月2の謎

なぜ2006年に意味があると思わず、最初は2020-01-01を指定したらダメでした

では一体この2006年1月2日という特別な日は、なんの日なのか?

(…中略…)

答えは単純だ。これはアメリカ式の時刻の順番なのだ。”1月2日午後3時4分5秒2006年”(つまり「自然な順番」で1, 2, 3, 4, 5, 6)を指しているのである。

参考

1
2
	// 検索キーの日付
  keyDay := time.Now().Format("2006-01-02")

検索

GetItem
parmsにパラメータをセットして、GetItemに渡しています

パラメータ

GetItemInput
TableNameはDynamoDBのテーブル名をそのまま
check_dateはDynamoDBのプライマリキーでJson形式で検索したい値を指定すれば値を取得できます
正直、Key: map[string]*dynamodb.AttributeValue{を理解できてはいないのです…
急にでてくる大文字のSStringを表しています

S
An attribute of type String. For example:
“S”: “Hello”
Type: String
Required: No

参考

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
	params := &dynamodb.GetItemInput{
		TableName: aws.String(DBTABLE),

		Key: map[string]*dynamodb.AttributeValue{
			"check_date": {
				S: aws.String(keyDay), // 日付は文字列で渡す必要が有り、日付自体はDBにこのフォーマットで登録されている
			},
		},
	}
	resp, err := svc.GetItem(params)
	if err != nil {
		fmt.Println(err.Error())
	}

取得した値のUnmarshal

小分けにして説明をしていく

1
2
3
4
5
6
7
8
9
	// respの結果を確認
	if len(resp.Item) != 0 {
		dmm := &DmmData{}
		if err := dynamodbattribute.UnmarshalMap(resp.Item, dmm); err != nil {
			fmt.Println("Unmarshal Error", err)
		}

		j, _ := json.Marshal(dmm)
		fmt.Println(string(j)

取得した値はresp.Itemの中に入っています
dynamodbattribute
dynamodbattribute.UnmarshalMapは、dynamodbattributeをGoの型に変換します

DmmData(構造体)のポインタ型(メモリアドレス)を初期化してdmmへ格納

1
dmm := &DmmData{}

初期化しているため、fmt.Printlndmmを表示すると

1
&{ 0}

ここの挙動を正しく理解できていないのですが、dmm内にDynamoDBからヒットした結果を格納してくれます
res.Item,の後はポインタ型を要求されるため、先程ポインタ型でdmmに構造体の型を初期化しました

1
dynamodbattribute.UnmarshalMap(resp.Item, dmm)
補足

dmmをポインタ型にしなかった場合のエラー

1
Unmarshal Error InvalidUnmarshalError: cannot unmarshal to non-pointer value, got main.DmmData

fmt.Printlndmmを表示すると検索結果が格納されています

1
&{2020-02-16 4770}

dmm構造体をJsonに変換しています
*dmm指定でデリファレンスする必要ないのかと思ったのですが、
どっちを指定しても意図したJsonが返ってきます…

1
2
		j, _ := json.Marshal(dmm)
		fmt.Println(string(j))
出力結果

DynamoDBから最新値をJson形式で取得することができました

{"check_date":"2020-02-16","remainig_capacity":4770}

感想

DynamoDBのSDKはポインタが多くて把握できていないので、
Goの勉強もかねて解説していきたいです。
次回は今回取得した値をSQSに格納する部分を予定

参考

https://qiita.com/ezaki/items/2a9f10c53d958070ca95
https://qiita.com/sakayuka/items/4af7fead94d589716f4d