Node.jsでDynamoDBを操作する(CRUD処理編)

#概要
表題通り、Node.jsでDynamoDBを操作する記事です。

##基本情報
操作TBL
![スクリーンショット 2021-07-29 19.07.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/599049/c8511cbb-7d67-3745-ceea-7b232d7da463.png)

```shell:ディレクトリ構成
~/develop/study/aws/node/dynamo $ tree
.
├── crud
│   ├── OlympicCreateItem.js
│   ├── OlympicDeleteItem.js
│   ├── OlympicGetItem.js
│   └── OlympicUpdateItem.js
├── data
│   └── olympicData.json
└── migration
    ├── OlympicCreateTable.js
    └── OlympicLoadData.js

3 directories, 7 files
```

##事前準備

```javascript:TBL作成(OlympicCreateTable.js)
var AWS = require("aws-sdk");

AWS.config.update({
  region: "ap-northeast-1"
});

var dynamodb = new AWS.DynamoDB();

var params = {
    TableName : "Olympic",
    KeySchema: [       
        { AttributeName: "Id", KeyType: "HASH"},  //Partition key
        { AttributeName: "Country", KeyType: "RANGE" }  //Sort key
    ],
    AttributeDefinitions: [       
        { AttributeName: "Id", AttributeType: "N" },
        { AttributeName: "Country", AttributeType: "S" }
    ],
    ProvisionedThroughput: {       
        ReadCapacityUnits: 10, 
        WriteCapacityUnits: 10
    }
};

dynamodb.createTable(params, function(err, data) {
    if (err) {
        console.error("TBL作成失敗：", JSON.stringify(err, null, 2));
    } else {
        console.log("TBL作成成功：", JSON.stringify(data, null, 2));
    }
});
```

```json:olympicData.json
[
    {
        "Id": 1,
        "Country": "日本",
        "Medal": {
            "GoldMedal": 11,
            "SilverMedal": 11,
            "BronzeMedal": 11
        }
    },
    {
        "Id": 2,
        "Country": "アメリカ",
        "Medal": {
            "GoldMedal": 10,
            "SilverMedal": 8,
            "BronzeMedal": 7
        }
    },    
    {
        "Id": 3,
        "Country": "中国",
        "Medal": {
            "GoldMedal": 5,
            "SilverMedal": 5,
            "BronzeMedal": 5
        }
    }
]
```

```shell:TBL作成の実行結果
~/develop/study/aws/node/dynamo/migration $ node OlympicCreateTable.js 
TBL作成成功： {
  "TableDescription": {
    "AttributeDefinitions": [
      {
        "AttributeName": "Country",
        "AttributeType": "S"
      },
      {
        "AttributeName": "Id",
        "AttributeType": "N"
      }
    ],
    "TableName": "Olympic",
    "KeySchema": [
      {
        "AttributeName": "Id",
        "KeyType": "HASH"
      },
      {
        "AttributeName": "Country",
        "KeyType": "RANGE"
      }
    ],
    "TableStatus": "CREATING",
    "CreationDateTime": "2021-07-29T10:20:05.059Z",
    "ProvisionedThroughput": {
      "NumberOfDecreasesToday": 0,
      "ReadCapacityUnits": 10,
      "WriteCapacityUnits": 10
    },
    "TableSizeBytes": 0,
    "ItemCount": 0,
    "TableArn": "arn:aws:dynamodb:ap-northeast-1:696770525325:table/Olympic",
    "TableId": "5e5fb4bf-a314-496e-ad61-40387663f17f"
  }
}
```


```javascript:データのロード(OlympicLoadData.js)
var AWS = require("aws-sdk");
var fs = require('fs');

AWS.config.update({
    region: "ap-northeast-1",
});

var docClient = new AWS.DynamoDB.DocumentClient();

console.log("データのロード開始");

var Countries = JSON.parse(fs.readFileSync('../data/olympicData.json', 'utf8'));

Countries.forEach(function(country) {
    console.log(country)
    var params = {
        TableName: "Olympic",
        Item: {
            "Id":  country.Id,
            "Country": country.Country,
            "Medal":  country.Medal
        }
    };
    docClient.put(params, function(err, data) {
       if (err) {
           console.error("ロード失敗", country.Id, ". Error JSON:", JSON.stringify(err, null, 2));
       } else {
           console.log("ロード成功:", country.Id + country.Country);
       }
    });
});
```
```shell:データのロード
~/develop/study/aws/node/dynamo/migration $ node OlympicLoadData.js
データのロード開始
{
  Id: 1,
  Country: '日本',
  Medal: { GoldMedal: 11, SilverMedal: 11, BronzeMedal: 11 }
}
{
  Id: 2,
  Country: 'アメリカ',
  Medal: { GoldMedal: 10, SilverMedal: 8, BronzeMedal: 7 }
}
{
  Id: 3,
  Country: '中国',
  Medal: { GoldMedal: 5, SilverMedal: 5, BronzeMedal: 5 }
}
ロード成功: 3中国
ロード成功: 1日本
ロード成功: 2アメリカ
```

#CREATE文

```javascript:OlympicCreateItem.js
var AWS = require("aws-sdk");

AWS.config.update({
    region: "ap-northeast-1",
});

var docClient = new AWS.DynamoDB.DocumentClient();

var table = "Olympic";

var params = {
    TableName:table,
    Item:{
            "Id": 4,
            "Country": "ドイツ",
            "Medal": {
                "GoldMedal": 7,
                "SilverMedal": 7,
                "BronzeMedal": 7
            }
        }
};

docClient.put(params, function(err, data) {
    if (err) {
        console.error("Unable to add item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("Added item");
    }
});
```

#READ文
```javascript:OlympicGetItem.js
var AWS = require("aws-sdk");

AWS.config.update({
    region: "ap-northeast-1",
});

var docClient = new AWS.DynamoDB.DocumentClient();

var table = "Olympic";

var params = {
    TableName: table,
    Key:{
        "Id": 1,
        "Country": '日本'
    }
};

docClient.get(params, function(err, data) {
    console.log(params)
    console.log(data)
    if (err) {
        console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("GetItem succeeded:", JSON.stringify(data, null, 2));
    }
});
```

#UPDATE文
```javascript:OlympicUpdateItem.js
var AWS = require("aws-sdk");

AWS.config.update({
    region: "ap-northeast-1",
});

var docClient = new AWS.DynamoDB.DocumentClient()

var table = "Olympic";

var params = {
    TableName:table,
    Key:{
        "Id": 1,
        "Country": '日本'
    },
    UpdateExpression: "set Medal.GoldMedal = :g",
    ExpressionAttributeValues:{
        ":g":17,
    },
    ReturnValues:"UPDATED_NEW"
};

console.log("Updating the item...");
docClient.update(params, function(err, data) {
    if (err) {
        console.error("Unable to update item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("UpdateItem succeeded:", JSON.stringify(data, null, 2));
    }
});
```

#DELETE文
```javascript:OlympicDeleteItem.js
var AWS = require("aws-sdk");

AWS.config.update({
    region: "ap-northeast-1"
});

var docClient = new AWS.DynamoDB.DocumentClient();

var table = "Olympic";

var params = {
    TableName:table,
    Key:{
        "Id": 4,
        "Country": 'ドイツ'
    },
};

console.log("Attempting a conditional delete...");
docClient.delete(params, function(err, data) {
    if (err) {
        console.error("Unable to delete item. Error JSON:", JSON.stringify(err, null, 2));
    } else {
        console.log("DeleteItem succeeded:", JSON.stringify(data, null, 2));
    }
});
```