AWS SDKを利用してDynamoDBを操作する方法について確認します。「テーブル作成・削除」「アイテムの挿入・取得・更新・削除」について取り上げます。
目次
aws-sdkをインストール
aws-sdk
をインストールします。
yarn add aws-sdk
AWS.DynamoDB
Table作成|createTable
usersテーブル
を作成します。
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const dynamoDB = new AWS.DynamoDB()
const params = {
TableName: 'users',
AttributeDefinitions: [
{ AttributeName: 'user_id', AttributeType: 'N' }, // number
{ AttributeName: 'created_at', AttributeType: 'S' }, // string
{ AttributeName: 'post_id', AttributeType: 'N' } // number
],
KeySchema: [
{ AttributeName: 'user_id', KeyType: 'HASH' }, // Partition key
{ AttributeName: 'created_at', KeyType: 'RANGE' } // Sort key
],
LocalSecondaryIndexes: [
{
IndexName: 'post_local_index',
Projection: {
ProjectionType: 'ALL' // 射影される属性 > 全て
},
KeySchema: [
{ AttributeName: 'user_id', KeyType: 'HASH' },
{ AttributeName: 'post_id', KeyType: 'RANGE' }
]
}
],
GlobalSecondaryIndexes: [
{
IndexName: 'post_global_index',
Projection: {
ProjectionType: 'ALL'
},
KeySchema: [
{ AttributeName: 'post_id', KeyType: 'HASH' }
],
ProvisionedThroughput: {
ReadCapacityUnits: 10,
WriteCapacityUnits: 10
}
}
],
ProvisionedThroughput: {
ReadCapacityUnits: 10,
WriteCapacityUnits: 10
}
}
dynamoDB.createTable(params, (err, data) => {
if (err) {
console.error('Unable to create table. Error JSON:', JSON.stringify(err, null, 2))
} else {
console.log('Created table. Table description JSON:', JSON.stringify(data, null, 2))
}
})
以下、上記処理を実行して生成されたテーブルです。
認証方法について
ここでは、動作確認したいだけなので、 AWS.config.loadFromPath
で認証情報を設定しています。実際に利用する場合は、下記ページを参考に推奨順序の高い認証方法で実装することをお勧めします。
Table削除|deleteTable
usersテーブル
を削除します。
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const dynamoDB = new AWS.DynamoDB()
const params = { TableName: 'users' }
dynamoDB.deleteTable(params, (err, data) => {
if (err) {
console.error('Unable to delete table. Error JSON:', JSON.stringify(err, null, 2))
} else {
console.log('Deleted table. Table description JSON:', JSON.stringify(data, null, 2))
}
})
$ node delete-table.js
Deleted table. Table description JSON: {
"TableDescription": {
"TableName": "users",
"TableStatus": "DELETING",
"ProvisionedThroughput": {
"NumberOfDecreasesToday": 0,
"ReadCapacityUnits": 10,
"WriteCapacityUnits": 10
},
"TableSizeBytes": 0,
"ItemCount": 0,
"TableArn": "arn:aws:dynamodb:ap-northeast-1:XXXXXXXXXXXX:table/users",
"TableId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
}
}
AWS.DynamoDB.DocumentClient
Item挿入|put
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const documentClient = new AWS.DynamoDB.DocumentClient()
items = [
{ user_id: 1, post_id: 2, created_at: '1544741492', message: 'aaaaaaaaaaaaaa' },
{ user_id: 2, post_id: 9, created_at: '1544745092', message: 'bbbbbbbbbbbbbb' },
{ user_id: 3, post_id: 3, created_at: '1544748692', message: 'cccccccccccccc' },
{ user_id: 1, post_id: 5, created_at: '1544752292', message: 'dddddddddddddd' },
{ user_id: 5, post_id: 3, created_at: '1544755892', message: 'eeeeeeeeeeeeee' },
]
items.forEach(item => {
const params = {
TableName: 'users',
Item: {
'user_id': item.user_id,
'post_id': item.post_id,
'created_at': item.created_at,
'message': item.message
}
}
documentClient.put(params, (err, data) => {
if (err) console.log(err)
else console.log(data)
})
})
$ node put.js
{}
{}
{}
{}
{}
5項目追加されました。
単一Item取得|get
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const documentClient = new AWS.DynamoDB.DocumentClient()
const params = {
TableName: 'users',
Key: {
'user_id': 1,
'created_at': '1544752292'
}
}
documentClient.get(params, (err, data) => {
if (err) console.log(JSON.stringify(err, null, 2))
else console.log(JSON.stringify(data, null, 2))
})
$ node get.js
{
"Item": {
"message": "dddddddddddddd",
"user_id": 1,
"created_at": "1544752292",
"post_id": 5
}
}
条件に一致するItem取得|query
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const documentClient = new AWS.DynamoDB.DocumentClient()
const params = {
TableName: 'users',
KeyConditionExpression: 'user_id = :user_id and created_at >= :created_at',
ExpressionAttributeValues: {
':user_id': 1,
':created_at': '1544752292'
}
}
documentClient.query(params, (err, data) => {
if (err) console.log(JSON.stringify(err, null, 2))
else console.log(JSON.stringify(data, null, 2))
})
$ node query.js
{
"Items": [
{
"message": "dddddddddddddd",
"user_id": 1,
"created_at": "1544752292",
"post_id": 5
}
],
"Count": 1,
"ScannedCount": 1
}
条件に一致するItem取得|scan
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const documentClient = new AWS.DynamoDB.DocumentClient()
const params = {
TableName: 'users',
FilterExpression: 'message = :message',
ExpressionAttributeValues: { ':message': 'cccccccccccccc' }
}
documentClient.scan(params, (err, data) => {
if (err) console.log(JSON.stringify(err, null, 2))
else console.log(JSON.stringify(data, null, 2))
})
$ node scan.js
{
"Items": [
{
"message": "cccccccccccccc",
"user_id": 3,
"created_at": "1544748692",
"post_id": 3
}
],
"Count": 1,
"ScannedCount": 5
}
全Item取得|scan
Query
Scan
の結果セットにはデータ制限( 1MB
)があるので、注意が必要です。全件取得したつもりが、データ制限により 1MB
分のitemしか取得されていなかったという意図しない動作が発生しうります。
データ制限を越えると、クエリ応答
に LastEvaluatedKey
がセットされます。 以下実装では、LastEvaluatedKey
が設定されている間、繰り返しscanをして全item取得しています。
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const documentClient = new AWS.DynamoDB.DocumentClient()
const scanAll = async () => {
let params = {
TableName: 'users',
}
let items = []
const scan = async () => {
console.log('execute scan')
console.log(params)
const result = await documentClient.scan(params).promise()
items.push(...result.Items)
if (result.LastEvaluatedKey) {
params.ExclusiveStartKey = result.LastEvaluatedKey
await scan()
}
}
try {
await scan()
return items
} catch (err) {
console.error(`[Error]: ${JSON.stringify(err)}`)
return err
}
}
(async () => {
const items = await scanAll()
})()
$ node scanAll.js
execute scan
{ TableName: 'users' }
execute scan
{ TableName: 'users',
ExclusiveStartKey: { user_id: 9, created_at: '1544741492' } }
execute scan
{ TableName: 'users',
ExclusiveStartKey: { user_id: 5, created_at: '1544741492' } }
Item更新|update
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const documentClient = new AWS.DynamoDB.DocumentClient()
const params = {
TableName: 'users',
Key: {
user_id: 3,
created_at: '1544748692'
},
UpdateExpression: 'set message = :message, post_id=:post_id',
ExpressionAttributeValues: {
':message': 'update_xxxxxxxxxxxxxxx',
':post_id': 100
},
ReturnValues: 'ALL_NEW'
}
documentClient.update(params, (err, data) => {
if (err) console.log(JSON.stringify(err, null, 2))
else console.log(JSON.stringify(data, null, 2))
})
$ node update.js
{
"Attributes": {
"message": "update_xxxxxxxxxxxxxxx",
"user_id": 3,
"created_at": "1544748692",
"post_id": 100
}
}
Item削除|delete
const AWS = require('aws-sdk')
AWS.config.loadFromPath('./config.json')
const documentClient = new AWS.DynamoDB.DocumentClient()
const params = {
TableName: 'users',
Key: {
user_id: 1,
created_at: '1544752292'
}
}
documentClient.delete(params, (err, data) => {
if (err) console.log(JSON.stringify(err, null, 2))
else console.log(JSON.stringify(data, null, 2))
})
$ node delete.js
{}
参考
- Node.js と DynamoDB – Amazon DynamoDB
- https://github.com/aws/aws-sdk-js/blob/master/lib/dynamodb/document_client.js
- https://docs.aws.amazon.com/ja_jp/AWSJavaScriptSDK/latest/AWS/DynamoDB.html
- https://docs.aws.amazon.com/ja_jp/AWSJavaScriptSDK/latest/AWS/DynamoDB/DocumentClient.html
- Node.js で認証情報を設定する – AWS SDK for JavaScript