如何在更新 Amazon DynamoDB 中的项目时执行多个操作?

How to execute multiple operations while updating an item in Amazon DynamoDB?

我正在尝试更新 Amazon DynamoDB 中的项目。我想执行一个加法和减法运算,但是我无法完成我的目标。

这里是函数,ddb是class的一个实例 AWS.DynamoDB.DocumentClient:

function updateLecture(event){
    const params = {
        TableName: 'lecture',
        Key: {
            'lecture_id': Number.parseInt(event.lecture_id)
        },
        UpdateExpression: 'SET #free = :total - (#total + #free)',
        ExpressionAttributeValues: {
            ':total': event.total
        },
        ExpressionAttributeNames: {
            "#total" : "total",
            "#free" : "free"
        },
        ReturnValues : 'UPDATED_NEW'
    }
    
    return ddb.update(params).promise();
}

当我尝试 运行 函数时,出现以下错误:

"errorType": "ValidationException",
"errorMessage": "Invalid UpdateExpression: Syntax error; token: \"+\", near: \"#total + #free\""

我试过使用括号,但总是收到同样的错误。

恐怕我不能使用多个操作,但我在 docs 中找不到任何痕迹。无论如何,有没有办法使用多个操作?

刚刚在 DynamoDB 控制台中尝试了以下 PartiQL 语句,它运行良好:

// Works just fine
UPDATE "ddb-playground" 
SET myNumA = 10 - (myNumB + myNumA)
WHERE PK = 'foo' AND SK = 'bar'

它运行得很好,所以至少这里没有基本限制。

但是,就像您一样,我无法让 JS SDK 使用 UpdateExpression 执行此操作,无论我尝试什么,我都会遇到语法错误。所以看起来 JS SDK 仅限于数值的单个算术表达式。

// Fails with:
//
// ValidationException: Invalid UpdateExpression: Syntax error; token: "+", near: "myNumB + myNumA"
import AWS from "aws-sdk"
const ddb = new AWS.DynamoDB()

await ddb.putItem({
    TableName: "ddb-playground",
    Item: {
        PK: {S: "foo"},
        SK: {S: "bar"},
        myNumA: {N: "10"},
        myNumB: {N: "20"}
    }
}).promise()


await ddb.updateItem({
    TableName: "ddb-playground",
    Key: {
        PK: {S: "foo"},
        SK: {S: "bar"}
    },
    UpdateExpression: "SET myNumA = :newVal - (myNumB + myNumA)",
    ExpressionAttributeValues: {
        ":newVal": {N: "30"}
    }
}).promise()

那么,也许您唯一的选择就是为此实际使用 PariQL?

await ddb.executeStatement({
  Statement: 'UPDATE "ddb-playground" SET myNumA = ? - (myNumB + myNumA) WHERE PK = ? AND SK = ?',
  Parameters: [{N: "30"}, {S: "foo"}, {S: "bar"}]
}).promise()