在 UpdateExpression 上使用 DELETE 集更新 DynamoDB 记录失败并显示 node.js
Updating DynamoDB record with DELETE Set on UpdateExpression fails with node.js
我正在尝试对 DynamoDB.DocumentClient
实例执行更新调用,使用 AWS SDK
和以下代码片段中的负载:
const AWS = require('aws-sdk')
const DynamoDB = new AWS.DynamoDB.DocumentClient()
...
const TableName = 'MyTable'
const Key = { PK: 'MyPK', SK: 'MySK' }
const operation = 'DELETE'
const myId = 'abcde'
const currentRecord = await DynamoDB.get({TableName, Key)
DynamoDB.update({
TableName,
Key,
UpdateExpression: `
${operation} myIds :valuesToModify,
version :incrementVersionBy
`,
ConditionExpression: `version = :version`,
ExpressionAttributeValues: {
":version": currentRecord.version,
":incrementVersionBy": 1,
":valuesToModify": DynamoDB.createSet([myId])
}
})...
我收到此错误结果:
ERROR Invoke Error
{
"errorType":"Error",
"errorMessage":"ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function;
operator: DELETE, operand type: NUMBER, typeSet: ALLOWED_FOR_DELETE_OPERAND",
"stack":[...]
}
有趣的是,如果将 operation
更改为 ADD
效果很好。
任何可能有助于理解为什么 ADD
有效而不是 DELETE
的线索 and/or 如何修复 and/or 但与此更新操作兼容的替代方法是高度赞赏!
此处唯一可行的解决方法是不使用 DELETE 操作,而是查询该项目,在数组中找到要删除的索引,然后通过 REMOVE 操作将其删除:
在这种情况下,arrayField 包含一个用户数组,我想按用户的电话号码删除。
const dataStore = await dynamodb.get(queryParams).promise();
let i=0; //save the index
for(i = 0; i < dataStore.Item.myTable.length; i++){
if(dataStore.Item.arrayField[i].phone === phoneNumber)
{
break;
}
}
if(i < dataStore.Item.arrayField.length){
const updateStoreParams = {
TableName: tableName,
Key: storeTableKey,
UpdateExpression: `REMOVE arrayField[${i}]`,
}
await dynamodb.update(updateStoreParams).promise().catch((err) => {
console.log(err);
throw err;
});
}
结果是我没有注意的语义错误。
当 ${operation}
为 ADD
时,UpdateExpression
的 version
字段将起作用,因为它是一个数字增量。
当 ${operation}
为 DELETE
时,version
不起作用,因为错误指出它是 Incorrect operand type for operator or function
,因为它仅适用于 [=20] =] 根据文档。
错误一开始有点误导,但当我尝试使用其他 SDK 实现时,我最终遇到了同样的错误,然后我尝试关注 UpdateExpression
部分,发现我必须重构为这样的东西才能工作:
// Notice below that I inject ADD if operation is DELETE and a comma otherwise
DynamoDB.update({
TableName,
Key,
UpdateExpression: `
${operation} socketIds :valuesToModify
${operation == 'DELETE' ? 'ADD' : ','} version :incrementVersionBy
`,
ConditionExpression: `version = :version`,
ExpressionAttributeValues: {
':version': channelRecord.version,
':incrementVersionBy': 1,
':valuesToModify': DynamoDB.createSet([socketId])
}
})
希望以后对其他人有用!
我正在尝试对 DynamoDB.DocumentClient
实例执行更新调用,使用 AWS SDK
和以下代码片段中的负载:
const AWS = require('aws-sdk')
const DynamoDB = new AWS.DynamoDB.DocumentClient()
...
const TableName = 'MyTable'
const Key = { PK: 'MyPK', SK: 'MySK' }
const operation = 'DELETE'
const myId = 'abcde'
const currentRecord = await DynamoDB.get({TableName, Key)
DynamoDB.update({
TableName,
Key,
UpdateExpression: `
${operation} myIds :valuesToModify,
version :incrementVersionBy
`,
ConditionExpression: `version = :version`,
ExpressionAttributeValues: {
":version": currentRecord.version,
":incrementVersionBy": 1,
":valuesToModify": DynamoDB.createSet([myId])
}
})...
我收到此错误结果:
ERROR Invoke Error
{
"errorType":"Error",
"errorMessage":"ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function;
operator: DELETE, operand type: NUMBER, typeSet: ALLOWED_FOR_DELETE_OPERAND",
"stack":[...]
}
有趣的是,如果将 operation
更改为 ADD
效果很好。
任何可能有助于理解为什么 ADD
有效而不是 DELETE
的线索 and/or 如何修复 and/or 但与此更新操作兼容的替代方法是高度赞赏!
此处唯一可行的解决方法是不使用 DELETE 操作,而是查询该项目,在数组中找到要删除的索引,然后通过 REMOVE 操作将其删除:
在这种情况下,arrayField 包含一个用户数组,我想按用户的电话号码删除。
const dataStore = await dynamodb.get(queryParams).promise();
let i=0; //save the index
for(i = 0; i < dataStore.Item.myTable.length; i++){
if(dataStore.Item.arrayField[i].phone === phoneNumber)
{
break;
}
}
if(i < dataStore.Item.arrayField.length){
const updateStoreParams = {
TableName: tableName,
Key: storeTableKey,
UpdateExpression: `REMOVE arrayField[${i}]`,
}
await dynamodb.update(updateStoreParams).promise().catch((err) => {
console.log(err);
throw err;
});
}
结果是我没有注意的语义错误。
当 ${operation}
为 ADD
时,UpdateExpression
的 version
字段将起作用,因为它是一个数字增量。
当 ${operation}
为 DELETE
时,version
不起作用,因为错误指出它是 Incorrect operand type for operator or function
,因为它仅适用于 [=20] =] 根据文档。
错误一开始有点误导,但当我尝试使用其他 SDK 实现时,我最终遇到了同样的错误,然后我尝试关注 UpdateExpression
部分,发现我必须重构为这样的东西才能工作:
// Notice below that I inject ADD if operation is DELETE and a comma otherwise
DynamoDB.update({
TableName,
Key,
UpdateExpression: `
${operation} socketIds :valuesToModify
${operation == 'DELETE' ? 'ADD' : ','} version :incrementVersionBy
`,
ConditionExpression: `version = :version`,
ExpressionAttributeValues: {
':version': channelRecord.version,
':incrementVersionBy': 1,
':valuesToModify': DynamoDB.createSet([socketId])
}
})
希望以后对其他人有用!