AWS CLI で DynamoDB のデータ型記述子なしに複数 json データ投入
TL;DR
- DynamoDB の "N" や "S" などのデータ型記述子をもたない生の json データを複数投入する shell のワンライナーを作りました
TABLE="<YOUR TABLE>"
JSON_FILE="<YOUR JSON FILE NAME>"
# json の配列を要素(record)に分解して、" を ' に置換してデータ投入
jq -c '.[]' "${JSON_FILE}" | sed -e "s/\"/'/g" \
| while read -r record; do aws dynamodb execute-statement --statement "INSERT INTO ${TABLE} value ${record}"; done
この記事を読んで欲しい人
- AWS CLI から DynamoDB に複数の生 json データを投入したい人
前提
本記事では、下記を前提とします。
-
aws
コマンドが使える環境があること -
jq
コマンドが使える環境であること - DynamoDB に触れたことがあり、基本的な知識があること
DynamoDB への json データ投入なんか面倒じゃないか...?
最近、勉強のために DynamoDB を触っており、サンプルデータの投入をやろうとして、json データの投入方法を軽く調べたのですが、既存の方法では次のようなアプローチが知られているようでした。
- AWS CLI を使って、"N" や "S" などのDynamoDB データ記述子をもつ独自の json ファイルを作成してデータを投入
- python などのスクリプトを書いて、データ投入
両者とも素晴らしい情報を共有して頂いている記事なのですが、私はこれらのアプローチに次の課題があると感じました。
-
- の方法は、DynamoDB データ記述子をもつ json ファイルを作るのが面倒。また、1回のコマンドで、24件までしかデータが投入できない制約がある。
-
- 実装量は多くないがちょっとしたデータ投入をするために、python 等の言語環境を用意するのは手間。shell で済ませたい。
さらに調べてみると、DynamoDB shell と PartiQL というものがあることがわかりました。
こちらの記事を読んだところ、AWS CLI から PartiQL を利用することで課題解決ができそうなことがわかりました。
しかし、PartiQL は複数 json データ(json の配列)を一括投入する VALUES
句は提供していなさそうだったので、shell でデータ数分のコマンドをループ実行することにしました。
実際にデータ投入してみる
サンプルデータを用意して、実際に json データの投入をやってみます。
データ例
例として、部門が管理するデータ?みたいなものを扱います。
サンプルデータは、3階層程度のネストをもつように LLM にお願いして作成しました。
[
{
"department": "開発部",
"projects": [
{
"name": "プロジェクトA",
"tasks": [
{
"id": 1,
"title": "API設計"
},
{
"id": 2,
"title": "DBスキーマ作成"
}
]
},
{
"name": "プロジェクトB",
"tasks": [
{
"id": 3,
"title": "UIプロトタイプ作成"
},
{
"id": 4,
"title": "テストケース設計"
}
]
}
]
},
{
"department": "営業部",
"projects": [
{
"name": "新規顧客開拓",
"tasks": [
{
"id": 5,
"title": "見積書作成"
},
{
"id": 6,
"title": "プレゼン資料準備"
}
]
}
]
}
]
データ投入先の DynamoDB は下記の条件で作成しました。
- DynamoDB のデータ投入先テーブル
- AWS コンソール上から、テーブル名
Department
を作成 -
department
(S
型)をハッシュキーに設定
- AWS コンソール上から、テーブル名
コマンド実行例
データ投入実施
# json の配列を要素(record)毎に分解して、" を ' に置換してデータ投入
jq -c '.[]' department.json | sed -e "s/\"/'/g" \
| while read -r record; do aws dynamodb execute-statement --statement "INSERT INTO Department value ${record}"; done
{
"Items": []
}
{
"Items": []
}
データ投入確認
aws dynamodb execute-statement --statement "SELECT * FROM Department;"
{
"Items": [
{
"department": {
"S": "営業部"
},
"projects": {
"L": [
{
"M": {
"name": {
"S": "新規顧客開拓"
},
"tasks": {
"L": [
{
"M": {
"id": {
"N": "5"
},
"title": {
"S": "見積書作成"
}
}
},
{
"M": {
"id": {
"N": "6"
},
"title": {
"S": "プレゼン資料準備"
}
}
}
]
}
}
}
]
}
},
{
"department": {
"S": "開発部"
},
"projects": {
"L": [
{
"M": {
"name": {
"S": "プロジェクトA"
},
"tasks": {
"L": [
{
"M": {
"id": {
"N": "1"
},
"title": {
"S": "API設計"
}
}
},
{
"M": {
"id": {
"N": "2"
},
"title": {
"S": "DBスキーマ作成"
}
}
}
]
}
}
},
{
"M": {
"name": {
"S": "プロジェクトB"
},
"tasks": {
"L": [
{
"M": {
"id": {
"N": "3"
},
"title": {
"S": "UIプロトタイプ作成"
}
}
},
{
"M": {
"id": {
"N": "4"
},
"title": {
"S": "テストケース設計"
}
}
}
]
}
}
}
]
}
}
]
}
SELECT
で取得した json は DynamoDB のデータ記述子を含んで出力されました。こちらもデータ記述子を含まない json で出力したいところですが、今後の課題とします。
まとめ
本記事では、AWS CLI の PartiQL を利用して、複数の json をデータ投入可能な shell ワンライナーを取り扱いました。
DynamoDB へのデータ投入で困っていた人の助けとなれば幸いです。
PartiQL に関しては SQL に慣れた開発者であれば、DynamoDB でも見慣れたクエリを使えて便利そうなので、今後より詳しく勉強していきたいと思いました。
Discussion