[JAWS-UG CLI] DynamoDB:#2 アイテムの操作 (ハッシュキーのみの場合)


http://jawsug-cli.doorkeeper.jp/events/18571 でのハンズオン資料です。

AWS CLIを利用して、DynamoDBのitemを作成、更新、削除してみます。
あわせて、簡単なスキャンやクエリーの使い方を確認してみます。

* put-item
* get-item
* delete-item
* scan
* query


前提条件
========

## DynamoDBへの権限

* DynamoDBに対してフル権限があること。

## AWS CLIのバージョン

以下のバージョンで動作確認済

* AWS CLI 1.7.7


0. 事前作業
===========

0.1. 変数の確認
------------------------

```bash:変数の確認:
cat << ETX

AWS_DEFAULT_REGION: ${AWS_DEFAULT_REGION}
DYNAMO_TABLE_NAME:  ${DYNAMO_TABLE_NAME}

ETX
```

0.2. DynamoDBテーブル名の指定
------------------------

DYNAMO_TABLE_NAMEが空か、想定と異なる場合は指定しなおします。

```bash:コマンド(例):
DYNAMO_TABLE_NAME='ProductCatalog'
```


1. アイテムの作成 (put-item)
============================

http://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStartedCreateTables.html の「ユースケース 1: 製品カタログ」のデータを投入します。

エントリ101
-----------

```bash:コマンド:
DYNAMO_ITEM_STRING='{"Id":{"N":"101"},"Title":{"S":"Book101Title"},"ISBN":{"S":"111-1111111111"},"Authors":{"SS":["Author1"]},"Price":{"N":"2"},"Dimensions":{"S":"8.5x11.0x0.5"},"PageCount":{"N":"500"},"InPublication":{"B":"true"},"ProductCategory":{"S":"Book"}}'
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb put-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --item "${DYNAMO_ITEM_STRING}"
```

```text:結果:
      (戻り値なし)
```


エントリ102
-----------

```bash:コマンド:
DYNAMO_ITEM_STRING='{"Id":{"N":"102"},"Title":{"S":"Book102Title"},"ISBN":{"S":"222-2222222222"},"Authors":{"SS":["Author1","Author2"]},"Price":{"N":"20"},"Dimensions":{"S":"8.5x11.0x0.8"},"PageCount":{"N":"600"},"InPublication":{"B":"true"},"ProductCategory":{"S":"Book"}}'
```

```bash:コマンド:
      echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb put-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --item "${DYNAMO_ITEM_STRING}"
```

```text:結果:
      (戻り値なし)
```


エントリ103
-----------

```bash:コマンド:
DYNAMO_ITEM_STRING='{"Id":{"N":"103"},"Title":{"S":"Book103Title"},"ISBN":{"S":"333-3333333333"},"Authors":{"SS":["Author1","Author2"]},"Price":{"N":"2000"},"Dimensions":{"S":"8.5x11.0x1.5"},"PageCount":{"N":"600"},"InPublication":{"B":"false"},"ProductCategory":{"S":"Book"}}'
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb put-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --item "${DYNAMO_ITEM_STRING}"
```

```text:結果:
      (戻り値なし)
```


エントリ201
-----------

```bash:コマンド:
DYNAMO_ITEM_STRING='{"Id":{"N":"201"},"Title":{"S":"18-Bike-201"},"Description":{"S":"201Description"},"BicycleType":{"S":"Road"},"Brand":{"S":"MountainA"},"Price":{"N":"100"},"Gender":{"S":"M"},"Color":{"SS":["Red","Black"]},"ProductCategory":{"S":"Bicycle"}}'
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
     JSON is valid
```

```bash:コマンド:
aws dynamodb put-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --item "${DYNAMO_ITEM_STRING}"
```

```text:結果:
      (戻り値なし)
```


エントリ202
-----------

```bash:コマンド:
DYNAMO_ITEM_STRING='{"Id":{"N":"202"},"Title":{"S":"21-Bike-202"},"Description":{"S":"202Description"},"BicycleType":{"S":"Road"},"Brand":{"S":"Brand-CompanyA"},"Price":{"N":"200"},"Gender":{"S":"M"},"Color":{"SS":["Green","Black"]},"ProductCategory":{"S":"Bicycle"}}'
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb put-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --item "${DYNAMO_ITEM_STRING}"
```

```text:結果:
      (戻り値なし)
```


エントリ203
-----------

```bash:コマンド:
DYNAMO_ITEM_STRING='{"Id":{"N":"203"},"Title":{"S":"19-Bike-203"},"Description":{"S":"203Description"},"BicycleType":{"S":"Road"},"Brand":{"S":"Brand-CompanyB"},"Price":{"N":"300"},"Gender":{"S":"W"},"Color":{"SS":["Red","Green","Black"]},"ProductCategory":{"S":"Bicycle"}}'
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb put-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --item "${DYNAMO_ITEM_STRING}"
```

```text:結果:
      (戻り値なし)
```


エントリ204
-----------

```bash:コマンド:
DYNAMO_ITEM_STRING='{"Id":{"N":"204"},"Title":{"S":"18-Bike-204"},"Description":{"S":"204Description"},"BicycleType":{"S":"Mountain"},"Brand":{"S":"Brand-CompanyB"},"Price":{"N":"400"},"Gender":{"S":"W"},"Color":{"SS":["Red"]},"ProductCategory":{"S":"Bicycle"}}'
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb put-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --item "${DYNAMO_ITEM_STRING}"
```

```text:結果:
      (戻り値なし)
```


エントリ205
-----------

```bash:コマンド:
DYNAMO_ITEM_STRING='{"Id":{"N":"205"},"Title":{"S":"20-Bike-205"},"Description":{"S":"205Description"},"BicycleType":{"S":"Hybrid"},"Brand":{"S":"Brand-CompanyC"},"Price":{"N":"500"},"Gender":{"S":"B"},"Color":{"SS":["Red","Black"]},"ProductCategory":{"S":"Bicycle"}}'
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb put-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --item "${DYNAMO_ITEM_STRING}"
```

```text:結果:
      (戻り値なし)
```


2. スキャン
===========


2.1. 全件表示
-------------

```bash:コマンド:
aws dynamodb scan --table-name ${DYNAMO_TABLE_NAME}
```

```json:結果
{
    "Count": 8, 
    "Items": [
        {
            "BicycleType": {
                "S": "Hybrid"
            }, 
            "Description": {
                "S": "205Description"
            }, 
            "Title": {
                "S": "20-Bike-205"
            }, 
            "Color": {
                "SS": [
                    "Black", 
                    "Red"
                ]
            }, 
            "Gender": {
                "S": "B"
            }, 
            "Price": {
                "N": "500"
            }, 
            "ProductCategory": {
                "S": "Bicycle"
            }, 
            "Id": {
                "N": "205"
            }, 
            "Brand": {
                "S": "Brand-CompanyC"
            }
        }, 
        {
            "BicycleType": {
                "S": "Road"
            }, 
            "Description": {
                "S": "203Description"
            }, 
            "Title": {
                "S": "19-Bike-203"
            }, 
            "Color": {
                "SS": [
                    "Black", 
                    "Green", 
                    "Red"
                ]
            }, 
            "Gender": {
                "S": "W"
            }, 
            "Price": {
                "N": "300"
            }, 
            "ProductCategory": {
                "S": "Bicycle"
            }, 
            "Id": {
                "N": "203"
            }, 
            "Brand": {
                "S": "Brand-CompanyB"
            }
        }, 
        {
            "BicycleType": {
                "S": "Road"
            }, 
            "Description": {
                "S": "202Description"
            }, 
            "Title": {
                "S": "21-Bike-202"
            }, 
            "Color": {
                "SS": [
                    "Black", 
                    "Green"
                ]
            }, 
            "Gender": {
                "S": "M"
            }, 
            "Price": {
                "N": "200"
            }, 
            "ProductCategory": {
                "S": "Bicycle"
            }, 
            "Id": {
                "N": "202"
            }, 
            "Brand": {
                "S": "Brand-CompanyA"
            }
        }, 
        {
            "BicycleType": {
                "S": "Road"
            }, 
            "Description": {
                "S": "201Description"
            }, 
            "Title": {
                "S": "18-Bike-201"
            }, 
            "Color": {
                "SS": [
                    "Black", 
                    "Red"
                ]
            }, 
            "Gender": {
                "S": "M"
            }, 
            "Price": {
                "N": "100"
            }, 
            "ProductCategory": {
                "S": "Bicycle"
            }, 
            "Id": {
                "N": "201"
            }, 
            "Brand": {
                "S": "MountainA"
            }
        }, 
        {
            "BicycleType": {
                "S": "Mountain"
            }, 
            "Description": {
                "S": "204Description"
            }, 
            "Title": {
                "S": "18-Bike-204"
            }, 
            "Color": {
                "SS": [
                    "Red"
                ]
            }, 
            "Gender": {
                "S": "W"
            }, 
            "Price": {
                "N": "400"
            }, 
            "ProductCategory": {
                "S": "Bicycle"
            }, 
            "Id": {
                "N": "204"
            }, 
            "Brand": {
                "S": "Brand-CompanyB"
            }
        }, 
        {
            "ISBN": {
                "S": "222-2222222222"
            }, 
            "Dimensions": {
                "S": "8.5x11.0x0.8"
            }, 
            "PageCount": {
                "N": "600"
            }, 
            "Price": {
                "N": "20"
            }, 
            "Title": {
                "S": "Book102Title"
            }, 
            "ProductCategory": {
                "S": "Book"
            }, 
            "InPublication": {
                "B": "dHJ1ZQ=="
            }, 
            "Authors": {
                "SS": [
                    "Author1", 
                    "Author2"
                ]
            }, 
            "Id": {
                "N": "102"
            }
        }, 
        {
            "ISBN": {
                "S": "333-3333333333"
            }, 
            "Dimensions": {
                "S": "8.5x11.0x1.5"
            }, 
            "PageCount": {
                "N": "600"
            }, 
            "Price": {
                "N": "2000"
            }, 
            "Title": {
                "S": "Book103Title"
            }, 
            "ProductCategory": {
                "S": "Book"
            }, 
            "InPublication": {
                "B": "ZmFsc2U="
            }, 
            "Authors": {
                "SS": [
                    "Author1", 
                    "Author2"
                ]
            }, 
            "Id": {
                "N": "103"
            }
        }, 
        {
            "ISBN": {
                "S": "111-1111111111"
            }, 
            "Dimensions": {
                "S": "8.5x11.0x0.5"
            }, 
            "PageCount": {
                "N": "500"
            }, 
            "Price": {
                "N": "2"
            }, 
            "Title": {
                "S": "Book101Title"
            }, 
            "ProductCategory": {
                "S": "Book"
            }, 
            "InPublication": {
                "B": "dHJ1ZQ=="
            }, 
            "Authors": {
                "SS": [
                    "Author1"
                ]
            }, 
            "Id": {
                "N": "101"
            }
        }
    ], 
    "ScannedCount": 8, 
    "ConsumedCapacity": null
}
```

2.2. アイテム数確認
-------------------

```bash:コマンド:
aws dynamodb scan --table-name ${DYNAMO_TABLE_NAME} --query 'Count'
```

```text:結果:
8
```


3. アイテムの操作
=================


3.1. アイテムの取得 (get-item)
------------------------------

```bash:コマンド:
k=Id
t=N
v=103
DYNAMO_KEY_STRING="{\"${k}\":{\"${t}\":\"${v}\"}}"; echo ${DYNAMO_KEY_STRING}
```

```json:結果:
      {"Id":{"N":"103"}}
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb get-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}"
```


```json:結果:
{
    "Item": {
        "ISBN": {
            "S": "333-3333333333"
        }, 
        "Dimensions": {
            "S": "8.5x11.0x1.5"
        }, 
        "PageCount": {
            "N": "600"
        }, 
        "Price": {
            "N": "2000"
        }, 
        "Title": {
            "S": "Book103Title"
        }, 
        "ProductCategory": {
            "S": "Book"
        }, 
        "InPublication": {
            "B": "ZmFsc2U="
        }, 
        "Authors": {
            "SS": [
                "Author1", 
                "Author2"
            ]
        }, 
        "Id": {
            "N": "103"
        }
    }
}
```

3.2. アイテムの更新 (update-item: 属性値の変更)
-----------------------------------------------

```bash:コマンド:
DYNAMO_UPDATE_STRING='{"Title":{"Action":"PUT","Value":{"S":"Book103Title2"}}}'
```

```bash:コマンド:
echo ${DYNAMO_UPDATE_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb update-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}" \
        --attribute-updates "${DYNAMO_UPDATE_STRING}"
```

```text:結果:
      (戻り値なし)
```

```bash:コマンド:
aws dynamodb get-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}"
```


```json:結果:
      {
        "Item": {
          "ISBN": {
              "S": "333-3333333333"
          },
          "Dimensions": {
              "S": "8.5x11.0x1.5"
          },
          "PageCount": {
              "N": "600"
          },
          "Price": {
              "N": "2000"
          },
          "Title": {
              "S": "Book103Title2"
          },
          "ProductCategory": {
              "S": "Book"
          },
          "InPublication": {
              "B": "ZmFsc2U="
          },
          "Authors": {
              "SS": [
                  "Author1",
                  "Author2"
              ]
          },
          "Id": {
              "N": "103"
          }
        }
      }
```


3.3. アイテムの更新 (update-item: 属性の削除)
---------------------------------------------

```bash:コマンド:
DYNAMO_UPDATE_STRING='{"PageCount":{"Action":"DELETE"}}'
```

```bash:コマンド:
echo ${DYNAMO_UPDATE_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb update-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}" \
        --attribute-updates "${DYNAMO_UPDATE_STRING}"
```

```text:結果:
      (戻り値なし)
```

```bash:コマンド:
aws dynamodb get-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}"
```


```json:結果:
      {
        "Item": {
          "ISBN": {
              "S": "333-3333333333"
          },
          "Dimensions": {
              "S": "8.5x11.0x1.5"
          },
          "Title": {
              "S": "Book103Title2"
          },
          "Price": {
              "N": "2000"
          },
          "ProductCategory": {
              "S": "Book"
          },
          "InPublication": {
              "B": "ZmFsc2U="
          },
          "Authors": {
              "SS": [
                  "Author1",
                  "Author2"
              ]
          },
          "Id": {
              "N": "103"
          }
        }
      }
```


3.4. アイテムの更新 (update-item: 属性の追加)
---------------------------------------------

```bash:コマンド:
DYNAMO_UPDATE_STRING='{"PageCount":{"Action":"PUT","Value":{"N":"601"}}}'
```

```bash:コマンド:
echo ${DYNAMO_UPDATE_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb update-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}" \
        --attribute-updates "${DYNAMO_UPDATE_STRING}"
```

```text:結果:
      (戻り値なし)
```

```bash:コマンド:
aws dynamodb get-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}"
```


```json:結果:
      {
        "Item": {
          "ISBN": {
              "S": "333-3333333333"
          },
          "Dimensions": {
              "S": "8.5x11.0x1.5"
          },
          "PageCount": {
              "N": "601"
          },
          "Price": {
              "N": "2000"
          },
          "Title": {
              "S": "Book103Title2"
          },
          "ProductCategory": {
              "S": "Book"
          },
          "InPublication": {
              "B": "ZmFsc2U="
          },
          "Authors": {
              "SS": [
                  "Author1",
                  "Author2"
              ]
          },
          "Id": {
              "N": "103"
          }
        }
      }
```


3.5. アイテムの削除 (delete-item)
---------------------------------

```bash:コマンド:
k=Id
t=N
v=103
DYNAMO_KEY_STRING="{\"${k}\":{\"${t}\":\"${v}\"}}"; echo ${DYNAMO_KEY_STRING}
```

```bash:コマンド:
echo ${DYNAMO_ITEM_STRING} | json_verify
```

```text:結果:
      JSON is valid
```

```bash:コマンド:
aws dynamodb delete-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}"
```

```text:結果:
      (戻り値なし)
```

```bash:コマンド:
aws dynamodb get-item \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key "${DYNAMO_KEY_STRING}"
```


```text:結果:
      (戻り値なし)
```


アイテム数確認を確認すると、1件減っていることがわかります。

```bash:コマンド:
aws dynamodb scan --table-name ${DYNAMO_TABLE_NAME} --query 'Count'
```

```text:結果:
7
```

4. クエリの試行
===============



4.1. クエリデータの作成
-----------------------

```bash:コマンド:
FILE_DYNAMO_QUERY='product-catalog-query.json'
```

```bash:コマンド:
k=Id
t=N
v=202
```

```bash:コマンド:
cat << EOS > ${FILE_DYNAMO_QUERY}
{
        "${k}": {
          "AttributeValueList": [
              {
                  "${t}": "${v}"
              }
          ],
          "ComparisonOperator": "EQ"
        }
}
EOS
```

```bash:コマンド:
cat ${FILE_DYNAMO_QUERY} | json_verify
```

```text:結果:
      JSON is valid
```


4.2. クエリの実行
-----------------

```bash:コマンド:
aws dynamodb query \
        --table-name ${DYNAMO_TABLE_NAME} \
        --key-conditions file://${FILE_DYNAMO_QUERY}
```

```json:結果:
{
    "Count": 1, 
    "Items": [
        {
            "BicycleType": {
                "S": "Road"
            }, 
            "Description": {
                "S": "202Description"
            }, 
            "Title": {
                "S": "21-Bike-202"
            }, 
            "Color": {
                "SS": [
                    "Black", 
                    "Green"
                ]
            }, 
            "Gender": {
                "S": "M"
            }, 
            "Price": {
                "N": "200"
            }, 
            "ProductCategory": {
                "S": "Bicycle"
            }, 
            "Id": {
                "N": "202"
            }, 
            "Brand": {
                "S": "Brand-CompanyA"
            }
        }
    ], 
    "ScannedCount": 1, 
    "ConsumedCapacity": null
}
```

完了
======

次に、update-tableコマンドを使用して、テーブルの属性を変更してみます。
http://qiita.com/tcsh/items/721453b3abbdefed78cb

余裕があれば、CloudWatchによるプロビジョンドスループットのアラーム設定をしてみても良いでしょう。