LoginSignup
0
0

More than 1 year has passed since last update.

DynamoDBで大量データをまとめて書き込みたい

Posted at

はじめに

勉強がてら家計簿アプリを作成していた際に詰まった事柄のメモです。
アプリが持つ機能として”毎月のクレジットカード明細を画面上からアップロードできる”機能を持たせようとしていて、
クレジットカード明細は毎月大体100件前後のデータだったので、
画面でポチッとアップロードボタンを押すとすぐ登録処理が完了してほしいと考えていました。

いざ実装しようとしてみると・・・

ググってみるとDynamoDBで複数件まとめてデータ登録するには"BatchWriteItem"を利用すればよいと分かったので、
100件ほどのデータをBatchWriteItemでputすると下記エラーにぶち当たりました。

 at '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]"

このタイミングでBatchWriteItemのAPIリファレンスを読んで見ると、(←まず最初に読むべきでした)
下記文言が書いてあり、どうやら1度に扱えるデータは25件までとのことが分かりました。
"BatchWriteItem"って名前なのにバッチ処理じゃないじゃん!

 A single call to BatchWriteItem can transmit up to 16MB of data over the network, consisting of up to 25 item put or delete operations. 

どうすれば1度にまとめて登録出来るのか

単純に「もし100件登録したいなら4回処理を回せばよいのか?」と思いましたが、実際にその通りでした。

まず登録したいデータを配列に持たせます。

let arrayProcessingData = [];

for (let index = 0; index < parsedData.length; index++) {
  //DBに書き込みたい各データを用意する処理部分は割愛
  let addData = {
    id: ID,
    paymentmonth: paymentmonth,
    dateofpayment: parsedData[index].dateOfPayment,
    payer: payer,
    payment: payment,
    paymentdestination: parsedData[index].paymentDestination,
  };
  arrayProcessingData.push(addData);
}

次に格納したいデータを25件ごとになるよう、requestArryに格納していきます。

let requestArry = [];
let current_requestArry = [];
let item_count = 0;

arrayProcessingData.forEach(function(obj, index) {
  item_count++;
  let requestObj = {
    PutRequest: {
      Item: obj,
    },
  };
  current_requestArry.push(requestObj);
  if (item_count % 25 == 0) {
    requestArry.push(current_requestArry);
    current_requestArry = [];
  }
});

//25件に満たない場合の格納処理
if (current_requestArry.length > 0 && current_requestArry.length != 25)
  requestArry.push(current_requestArry);

最後にrequestArryごとにbatchWrite処理を回していきます。

for (let x in requestArry) {
  let Dynamo_params = {};
  Dynamo_params = {
    RequestItems: {
      [TABLE_NAME]: requestArry[x],
    },
  };

  try {
    await docClient.batchWrite(Dynamo_params).promise();
    console.log("dynamoへ書き込めた!!");
  } catch (err) {
    console.log("dynamoへの書き込み処理でエラー:", err);
  }
}
return;

実装後の反省事項

batchWrite時のエラーキャッチが不十分な所もあるのですが、
何よりもBatchWriteItemのAPIリファレンスをちゃんと最後まで読めば、サンプル実装文にやりたいことに近いことが書いてあったことを見逃していたことです。
やっぱり公式ドキュメントを見ることは大事だと改めて思い知らされた事柄でした!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0