こうこく
作 ▸
改 ▸

Amazon DynamoDBの更新で「Attribute name is a reserved keyword」エラー

  • サンプルコードは Node 8.10, Python 3.7
  • このエラーが出るのは、項目の属性名がDynamoDBの予約語と被ってるせい。
  • ExpressionAttributeNames を使って、式の中の属性名もプレースホルダにする必要がある。

属性名に『Status』ってつけたら、予約語とかぶっちゃってたらしくて、条件付きUpdateしようとした時に Invalid UpdateExpression: Attribute name is a reserved keyword; reserved keyword: (属性名) エラーが出た。

じゃあ予約語は属性名に使えないのかと言うとそんなことはなくて、UpdateExpression 上では当該の属性名をプレースホルダにしておき、ExpressionAttributeNames で属性名を指定してやればいいらしい。

なお ExpressionAttributeNames 自体はupdate特有のものではなくて、クエリでも同じように使うみたいなので留意。

↓のコードは、MyTable の Id = 999 の項目について、Status = 1 ならば Status = 2 に更新する条件付きUpdate。

Node.js
'use strict';

const aws = require('aws-sdk');
const docClient = new aws.DynamoDB.DocumentClient({	
	region: 'ap-northeast-1',
});

docClient.update({
	TableName: 'MyTable',
	Key: {
		'Id': 999,
	},
	UpdateExpression: 'set #st = :newst',
	ConditionExpression: '#st = :oldst',
	ExpressionAttributeNames: {
		'#st': 'Status'  // ←属性名をプレースホルダにする。名前には井桁 (#) をつける。
	},
	ExpressionAttributeValues: {
		':newst': 2,
		':oldst': 1,
	},
	ReturnValues: 'UPDATED_NEW'
}, function(err, data) {
	if (err) {
		console.error('エラー', err);
	} else {
		console.log('更新成功', data);
	}
});

↓Pythonでもほぼ同じ。

import boto3

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

try:
	res = table.update_item(
		Key={
			'Id': 999,
		},
		UpdateExpression='set #st = :newst',
		ConditionExpression='#st = :oldst',
		ExpressionAttributeNames= {
			'#st': 'Status'
		},
		ExpressionAttributeValues={
			':newst': 2,
			':oldst': 1,
		},
		ReturnValues='UPDATED_NEW'
	)
	print('更新成功', res)
except Exception as e:
	print('エラー', e)
この記事に何かあればこちらまで (非公開)