如何在 DynamoDb 中进行插入,仅当键不存在时。

32

我想在DynamoDb中只添加一次id +一些值。如果该id已经存在,则不应执行任何操作或更新。

我可以使用以下方法:

search 

if not found > insert

if found > do nothing or update (for now do nothing is fine)

但是希望有更好的方法来实现它。ID应该是检查的关键。

以下是Node中的代码:

const dynamodbParams = {
        TableName: process.env.DYNAMODB_TABLE_BLICKANALYTICS,
        Item: {
          id: userId,
          createdAt: timestamp
        },
      };

      dynamoDb.put(dynamodbParams).promise()
      .then(data => {
        console.log('saved: ', dynamodbParams);
      })
      .catch(err => {
        console.error(err);
      });  

我在yml中使用这个。不知道是否有设置它的选项。

resources:
  Resources:
    DynamoDbTableExpenses:
      Type: 'AWS::DynamoDB::Table'
      DeletionPolicy: Retain
      Properties:
        AttributeDefinitions:
          -
            AttributeName: id
            AttributeType: S
          -  
            AttributeName: createdAt
            AttributeType: N
        KeySchema:
          -
            AttributeName: id
            KeyType: HASH
          -
            AttributeName: createdAt
            KeyType: RANGE            
        ProvisionedThroughput:
          ReadCapacityUnits: 1
          WriteCapacityUnits: 1
        TableName: ${self:provider.environment.DYNAMODB_TABLE_BLICKANALYTICS}

1个回答

70
您可以使用单个UpdateItem操作完成整个过程。
const dynamodbParams = {
    TableName: process.env.DYNAMODB_TABLE_BLICKANALYTICS,
    Key: {id: userId},
    UpdateExpression: 'SET createdAt = if_not_exists(createdAt, :ca)',
    ExpressionAttributeValues: {
        ':ca': {'S': timestamp}
    }
};
dynamoDb.updateItem(params, function(err, data) {
    if (err) {
        console.log(err, err.stack);
    } else {
        console.log(data);
    }
}

如果您只想在不存在的情况下进行插入,您可以轻松使用PutItem实现:

const dynamodbParams = {
    TableName: process.env.DYNAMODB_TABLE_BLICKANALYTICS,
    Item: {
        id: userId,
        createdAt: timestamp
    },
    ConditionExpression: 'attribute_not_exists(id)'
};
dynamodb.putItem(params, function(err, data) {
    if (err) {
        console.log(err, err.stack);
    } else {
        console.log(data);
    }
}

通过组合条件表达式更新表达式,您可以提出更复杂的方法来设置或更新项目中的属性。

请注意,我没有完全测试代码,如果有任何错误,请评论说明,但它应该可以工作。


2
谢谢更新,这似乎是我正在寻找的东西。在我的情况下,我不得不使用dynamoDb.put(dynamodbParams).promise(),因为"dynamoDb.putItem不是一个函数"。使用put可以解决这个问题。如果数据库中已经存在条目,现在我会收到“ConditionalCheckFailedException:条件请求失败”的消息。 - Tobi
可以说明这是一种称为“upsert”的标准数据库方法。它在像Postgres这样的旧数据库中使用。 - dwu39
2
我建议编辑此内容并让人们知道,如果ConditionExpression解析为“false”,则查询将返回400错误。 - Alberto S.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接