【AWS DynamoDB】大量のjsonデータ投入方法が意外と簡単だった

「DynamoDBに大量のjsonデータを取り込みたい!」

ここんところではオープンソースで提供されているデータもjson形式がいっぱい、DynamoDBはNoSQLのデータベースですから、簡単にjsonデータの取込が行えると思っていましたわ。

結果、簡単なやり方は見つかったのですのらすからすが、そこにたどり着くまでが長かったわ。

今回は試してみてダメだったやり方と、再現性が高いjson取込やり方をPythonコードとともに紹介していきます。

試したやり方は以下の二つでございます。

1. Pythonでboto3を利用し、ローカル環境からデータ投入やり方 

2. AWS CLIでjsonデータを喰わせるやり方(失敗)


解決やり方だけ知りたい方はでございますわね、1 だけ読んでくださるんですの。2はあたくしの苦戦の記録でございます。

1. DynamoDBへのjsonデータ大量投入: PythonとBoto3を利用する方法

Boto3はPythonで利用する、AWSリソース操作用のライブラリでございます。

Boto3にはbatch_writer_itemsっていうメソッドがあり、複数件のデータをDynamoDBに登録する際に役立ちます。

業務でも利用したことがあるので、Pythonでコーディングすればjsonデータの投入は出来るでしょうなーとは思ってましたわ。

そうですけど、今までLambdaを利用してBoto3を使ったPythonプログラムのコーディングはしていたのですのらすからすが、「ローカルから目的のDynamoDBテーブルにアクセスできるのでしょうか」っていう懸念があり、こっちの作業を後回しにしていましたわ。

今回はあたしの趣味でjsonをDynamoDBに読み込ませたいだけですから、出来ればLambdaを使うのではなく、ローカルからデータを投入したいんですの。

っていうことで、こっちのやり方ではでございますわね、ローカルからPython,Boto3を利用してDynamoDBにデータ投入します。

----------------------------------------------

手順は大きく、以下の3つでしたわ。

①ローカルへBoto3の導入

まずはローカル環境にBoto3をインストールします。ちなみにでございますわね、Windows環境でございます。

python -m pip install boto3

②AWS CLI の configureコマンドにて、アカウント情報を設定

(※AWS CLIをインストールしていない方はでございますわね、そちらを先にしてくださるんですの。)

アカウントIDとアクセスキーはでございますわね、マネジメントコンソールのIAMから取れたと思います。

$ aws configure
AWS Access Key ID [None]: アカウントID
AWS Secret Access Key [None]: アクセスキー
Default region name [None]: us-west-2
Default output format [None]: json

③Pythonでコーディング

さて、本題。ローカル環境で実行できるのかっていう懸念ですけれども、ぜんぜん心配いりませんでしたわ。

①と②の設定をしていれば、Lambdaで書くのとおんなじようにコーディングしたPythonコードを実行するだけで大丈夫。

コードはこおんな感じになりましたわ。

import json
import boto3
import decimal

TABLE_NAME = 'テーブル名'
FILE_PATH = 'jsonデータのファイルパス'

dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table(TABLE_NAME)


def put_items_dynamodb():
   put_item = convert_json_dict(FILE_PATH)

   try:
       with table.batch_writer() as batch:
           for item in put_item:
               batch.put_item(
                   Item=item
               )
   except Exception as e:
       print(e)


def convert_json_dict(json_file_name):
   with open(json_file_name) as json_file:
       d = json.load(json_file, parse_float=decimal.Decimal)

   return d


put_items_dynamodb()

私の対象にしたかったjsonファイルはこんな感じだったので↓

[
  {
    name:"matuko"
  },
  {
    name:"yoshiko"
  }
]

jsonファイルを読み込んで、1レコードずつfor文で回して処理すればよかったでございます。

こおんな簡単だったとは...


AWS CLIのconfigureを設定していればローカル実行したboto3のメソッドが上手いことやってくださる、っていうのが今回嬉しかったポイントでございます。

2. DynamoDBへのjsonデータ大量投入で駄目だった方法: AWS CLIの利用

いけないだったやり方も残しておきます。

AWS CLIを利用したやり方でございます。

このやり方ではでございますわね、障壁となる問題が2つありましたわ。

①DynamoDBに投入するjsonは独自の形式に変換する必要がある

②そもそも25件しか投入だめ。いけない

----------------------------------------------

まず①について。AWS CLIを利用したデータ投入やり方は公式ドキュメントに書いてあるので、こっち(https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/SampleData.LoadData.html)を参考にできます。

こっちのサンプルデータが以下のようになっています。投入したい素のjsonデータと異なる点がいくつも見受けられます。

【DynamoDBに登録する際のjsonの形式】
{
   "Forum": [ -> 1:テーブル名
       {
           "PutRequest": { -> 2:なんのリクエストか(他にはDeleteRequest)
               "Item": { -> 3:レコード一つ一つをItemで囲う必要有
                   "Name": {"S":"Amazon DynamoDB"}, → 4:"S"などのデータ型が必須
                   "Category": {"S":"Amazon Web Services"},
                   "Threads": {"N":"2"},
                   "Messages": {"N":"4"},
                   "Views": {"N":"1000"}
               }
           }
       },
       {
           "PutRequest": {
               "Item": {
                   "Name": {"S":"Amazon S3"},
                   "Category": {"S":"Amazon Web Services"}
               }
           }
       }
   ]
}

1: 大枠としてテーブル名で囲う必要がある

2: PutRequestかDeleteRequestか、いちいち記載が必要

3: Itemで1レコードを囲わなければいけない

4: 型を指定する必要がある

DynamoDBに投入するためのjson型にするにはでございますわね、上記4つを満たすようにデータを修正しなくっちゃいけないんでございます。

あたくしはPythonでデータ加工して、素のjsonからDynamoDB投入用にjsonを作成しましたが、なかなか手間でしたわ。

ちなみにでございますわね、jsonから、DynamoDB jsonに変換するだけであれば、海の外のサイトで簡単に変換できる「DynamoDB Converter Tool」っていう素晴らしいサイトがあります。とはいえ、Item や PutRequestの部分はあたしで作らなければいけないでございます。

さて、ここまで出来たところで、もう一つの問題が絶対に解消できません。それはでございますわね、②25件しか投入だめ。いけないんですの。

----------------------------------------------

②25件しか投入だめ。いけない、について。

先ほどのDynamoDB投入用のjsonファイルを作成し、AWS CLIからデータ投入するコマンドを入力しましたわ。ところが、以下のエラーが発生します。

aws dynamodb batch-write-item --request-items file://<ファイルパス>

'requestItems' failed to satisfy constraint: 
Map value must satisfy constraint: 
[Member must have length less than or equal to 25, 
Member must have length greater than or equal to 1]

「まじか?」

1件以上、25件以下でないと登録だめ。いけないとのこと。

DynamoDB投入用のjsonを作成するだけで2時間ほどかかっていたのですのらすから、かなりショックでございます。

つまり、「AWS CLIでは25件を超えるjsonデータの大量投入はだめ。いけない」っていうことですわね。

おいおい、意味ないじゃないかしら。

かなり時間をかけて上手いこと行かなかったのですのらすから、ショックでしたわ。

DynamoDBへの大量jsonデータ投入: まとめ

今回の作業の感想。

一つ目の感想。

AWSマネジメントコンソール上からjsonファイルを取り込めるようにしてほしいと思いましたわ。割とjsonファイルを読み込むことが多いはずですから、どうして対応されないのかが謎でございます。

二つ目の感想。

AWS CLIのbatch_write_itemが使えないなーっていうこと。公式ドキュメントを見てみたのですのらすからすが、やはり1件~25件までのデータしか登録だめ。いけないようでございます。ちなみにでございますわね、AWS公式のAWS CLIを利用したデータ登録の解説ページでは5件くらいのデータを対象にしていたのですのらすから、投入できて当然でしたわ。これはAWS中の人も使えないと思っているんじゃないかなーっていう感じがしますね。

三つ目の感想。

初めから横着せず、Pythonで書いておけば早かったなーっていう反省でございます。

あたくしはいつもGUIベースの操作に逃げてしまいがちですから、今回のように「一度やってしまえば次の作業効率も上がる作業」は集中してやってしまったほうがよいなと感じましたわ。

これでjsonファイルからDynamoDBへのデータ投入をLambdaの課金を気にせないでローカルから行えるようになったわけですのら、あたしの中では大きな成長でしたわ。

こおんな感じで、趣味での開発が成長につながるのはうれしいですし、発信できるのが嬉しいでございます。

それなら、お疲れ様でしたわ。

この記事が気に入ったらサポートをしてみませんか?