シェルスクリプトでDynamoDBテーブルにダミーデータを一括登録する

2021.10.21

こんにちは、CX事業本部 IoT事業部の若槻です。

今回は、シェルスクリプトでDynamoDBテーブルにダミーデータを一括登録してみました。

DynamoDBにダミーデータを登録したい

データをDynamoDBで管理するシステムの開発において、テーブルにデータがある程度の件数登録されている場合の挙動を見たり、データ件数が多い場合の負荷試験を行いたい場合があります。その際に選択肢として上がるのが以下のドキュメントの方法です。

しかし上記方法はCloudFormationスタックやLambda関数をAWSアカウント内に構築する必要があり、「数百件程度のダミーデータを投入するためだけに環境を汚したくない…」と思う場合があるかも知れません。

そこで数百件程度のダミーデータであれば難なく登録できるシェルスクリプトを作ってみました。

テーブル仕様

データの登録対象のテーブルの仕様です。

  • テーブル名:observationLog
  • パーティションキー:deviceId(文字列)
  • ソートキー:createdAt(数値)
  • キャパシティーモード:オンデマンド

シェルスクリプト

作成したシェルスクリプトが下記です。

put_:table_data.sh

#!/bin/bash
set -eux

TABLE_NAME=observationLog
DATA_COUNT=${1}
NOW=$(date +%s)

for i in `seq ${DATA_COUNT}`
do
  cat templateData.json | \
    jq '.createdAt.N='\"$((NOW+i))\" > \
    tmp.json

  aws dynamodb put-item \
    --table-name ${TABLE_NAME} \
    --item file://tmp.json
done

rm tmp.json
  • 作成したいアイテム数だけdynamodb put-itemをforループで実行します。
  • ループ数(作成したいアイテム数)はスクリプト実行時の引数で指定します。
  • ループ内では、テンプレートデータを元に作成したデータを一時ファイルに吐き出し、そのファイルを使用してput-itemでテーブルに作成していいます。

使い方

まずテンプレートとなるデータを取得します。

マネジメントコンソールで対象のテーブルにアクセスします。

テンプレートとして使用したいデータを開き、DynamoDB JSON形式でクリップボードにコピーします。

ファイルtemplateData.jsonを作成してコピーしたデータを記述します。

templateData.json

{
  "deviceId": {
    "S": "b483535f-5e9c-8855-a98e-05254e8475a2"
  },
  "createdAt": {
    "N": "1634824799"
  },
  "payload": {
    "M": {
      "temperature": {
        "N": "28"
      },
      "humidity": {
        "N": "80"
      },
      "barometer": {
        "N": "1013"
      },
      "wind": {
        "M": {
          "bearing": {
            "N": "255"
          },
          "velocity": {
            "N": "22"
          }
        }
      }
    }
  }
}

2つのファイルを同じパスに配置します。

  • put_table_data.sh
  • templateData.json

sh ./put_table_data.sh {作成したいデータ件数}を実行します。100件で試してみます。

$ sh ./put_table_data.sh 100

テーブルに100件のデータが追加できました。

スクリプトの実行時間は、私の環境では約1分16秒でした。

実行時間は、作成したいデータのサイズやその時のテーブルのWCUの逼迫度などにもよってくると思いますが、数百件程度であれば休憩時間などに自分のPCでキックすれば戻ってきた時に作成完了しているくらいかと思います。

BatchWriteは使わないの?

確かにBatchWriteのAPIを使用した方がデータ作成は早く終わりそうです。

当初私も使用を考えていましたがやめました。というのもBatchWriteで投入する場合はバッチデータを下記のような形式でJSONファイルに記述する必要があるのですが、これをシェルスクリプトで作成するのが難易度が高かったからです。頑張ればできなくも無さそうだったのですが、その結果可読性の悪いスクリプトが出来上がるのも嫌でした。よって数百件程度であれば1件ずつデータを作成するPutItemでいいやとなりました。

{
    "MusicCollection": [
        {
            "PutRequest": {
                "Item": {
                    "Artist": {"S": "No One You Know"},
                    "SongTitle": {"S": "Call Me Today"},
                    "AlbumTitle": {"S": "Somewhat Famous"}
                }
            }
        },
        {
            "PutRequest": {
                "Item": {
                    "Artist": {"S": "Acme Band"},
                    "SongTitle": {"S": "Happy Day"},
                    "AlbumTitle": {"S": "Songs About Life"}
                }
            }
        },
        {
            "PutRequest": {
                "Item": {
                    "Artist": {"S": "No One You Know"},
                    "SongTitle": {"S": "Scared of My Shadow"},
                    "AlbumTitle": {"S": "Blue Sky Blues"}
                }
            }
        }
    ]
}

しかし数千、数万というレベルの件数のデータを作成したいのであれば使うのもありだと思います。またシェルでなくPythonやNode.jsを使用した方がより構造的で可読性のあるスクリプトが作れると思います。

おわりに

シェルスクリプトでDynamoDBテーブルにダミーデータを一括登録してみました。

半年に一回くらい同じようなスクリプトを作ってるなーとかねてから思っていたので今回備忘録としてブログに残しました。

参考

以上