DynamoDBのBatchWriteでデータをまとめて書き換える – Nodejs版

DynamoDBには複数のアイテムを一気に書き換えるためのBatchWrite / BatchGet APIが用意されています。 ただ、BatchWriteがPUTオペレーションなので、更新時は事前にGETが必要となりま […]

広告ここから
広告ここまで

目次

    DynamoDBには複数のアイテムを一気に書き換えるためのBatchWrite / BatchGet APIが用意されています。

    ただ、BatchWriteがPUTオペレーションなので、更新時は事前にGETが必要となります。

    putItem メソッドによって、項目をテーブルに格納します。項目が存在する場合、その項目全体が置き換えられます。項目全体を置き換える代わりに固有の属性のみを更新する場合は、updateItem メソッドを使用できます。

    https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/JavaDocumentAPIItemCRUD.html#JavaDocumentAPIItemUpdate

    BatchGetしてからBatchWrite

    Queryでもいい気はしますが、今やっている作業的にGetの方が都合がよかったのでこの方法を採用します。

    対象のテーブルは「プライマリーキー: ID (String)」のみを想定しています。

    
    import { DynamoDB } from 'aws-sdk'
    const client = new DynamoDB.DocumentClient()
    
    const batchUpdate = async (tableName: string, ids: string[], overwriteProps: {[key: string]: any}) => {
      // 更新対象の元データをまとめて取得
      const { Responses } = await client.batchGet({
        RequestItems: {
          [tableName]: {
            Keys: ids.map(id => ({ID: id}))
          }
        }
      }).promise()
    
      // データがない場合はなにもしない
      if (!Responses || !Responses[tableName]) return
      const items = Responses[tableName]
      if (items.length < 1) return
    
      // batchWrite
      return client.batchWrite({
        RequestItems: {
          [tableName]: items.map(item => {
            const props = {...item}
    
            // 項目の更新処理
            Object.keys(overwriteProps).forEach(key => {
              const value = overwriteProps[key]
    
              // DELETEと入れた項目については削除する
              if (value === 'DELETE') {
                if (props[key]) delete props[key]
                return
              }
              props[key] = value
            })
            return {
              PutRequest: {
                Item: props
              }
            }
          })
        }
      }).promise()
    }

    使うときは以下の様な記述をします。

    batchUpdate('ExampleTable', [
      '6af3c7f3-c813-c2e6-007e-53763a28a819',
      '3844ffe9-aa9f-0489-565f-1e524a698a32'
    ], {
      dummyProp1: '1',
      dummyProp2: 'DELETE',
      dummyProp3: 2
    })

    雑感

    • DELTE操作を文字列で入れるのは実際どうなのかな
    • 1テーブルしか対応していないので、複数テーブルに処理かけたい場合は手を入れる必要あり
    • 件数が多い場合、何回かに分ける必要があるので、実際に使うには難あり
    広告ここから
    広告ここまで
    Home
    Search
    Bookmark