如何一次更新DynamoDB表中的多个项目

时间:2017-02-14 14:49:23

标签: amazon-web-services amazon-dynamodb nosql

我正在使用DynamoDB,我需要更新多个记录的特定属性。用伪语言写我的要求我想做一个更新,说“更新表设置relationshipStatus ='结婚',其中personKey IN(key1,key2,key3,...)”(假设personKey是我的DynamoDB表中的KEY。)

换句话说,我想用IN子句进行更新,或者我想可以将其称为批量更新。我找到了this链接,明确询问是否存在批处理更新等操作,而答案是否存在。但是,它没有提到IN子句。 documentation表示ConditionalExpressions支持IN子句(一次可以提供100个值)。但是,我不确定这样的IN子句是否适合我的情况,因为我仍然需要提供一个强制的KEY属性(它看起来似乎只有一个值 - 我可能是错的)而且我担心它会做一个每次更新的全表扫描。

所以我的问题是:如何同时实现多个DynamoDB记录的更新?目前几乎看起来我将不得不逐个调用每个密钥的更新声明,这只是感觉真的错了......

4 个答案:

答案 0 :(得分:21)

如您所述,DynamoDB不支持批量更新操作。您需要查询并获取要更新的所有记录的密钥。然后遍历该列表,一次更新一个项目。

答案 1 :(得分:3)

我不知道自从给出答案以来它是否已经改变,但是现在有可能

查看文档: https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_BatchWriteItem.html

我已经在javascript中使用了它(将新块映射到具有所需结构的对象数组:

let params = {}
let tableName = 'Blocks';

params.RequestItems[tableName] = _.map(newBlocks, block => {
    return {
        PutRequest: {
            Item: {
                'org_id': orgId,
                'block_id': block.block_id,
                'block_text': block.block_text
            },
            ConditionExpression: 'org_id <> :orgId AND block_id <> :block_id',
            ExpressionAttributeValues: {
                ':orgId': orgId,
                ':block_id': block.block_id
            }
        }
    }
})

docClient.batchWrite(params, function(err, data) {
   .... and do stuff with the result

您甚至可以混合使用putsdeletes

如果您使用的是测功机(由于测功机的支持,您不能混合使用em,但是您可以做的就是更新(使用create,因为它在幕后将转换为putWrite函数的位置)

var item1 = {email: 'foo1@example.com', name: 'Foo 1', age: 10};
var item2 = {email: 'foo2@example.com', name: 'Foo 2', age: 20};
var item3 = {email: 'foo3@example.com', name: 'Foo 3', age: 30};

Account.create([item1, item2, item3], function (err, acccounts) {
  console.log('created 3 accounts in DynamoDB', accounts);
});

请注意DynamoDB的限制(from the docs):

  

BatchWriteItem操作在一个或多个表中放置或删除多个项目。一次调用BatchWriteItem最多可以写入16 MB的数据,其中可以包含多达25个放置或删除请求。单个要写入的项目最大可以为400 KB。

如果我没记错的话,我认为dynogels将请求分成25个小块,然后发送出去,然后以一个承诺的形式收集它们并返回(尽管我对此不确定100%)-否则包装函数将非常容易组装

答案 2 :(得分:2)

DynamoDb并非设计为支持本机事务的关系数据库。最好设计架构,以避免一开始就进行多次更新。或者,如果您的情况不可行,请记住,在重组设计时可能会对其进行改进。

同时更新多个项目的唯一方法是使用DynamoDB提供的TransactionWrite操作。但是它有一个限制(例如最多25个)。因此请记住,您可能还应该在应用程序中做一些限制。尽管它非常昂贵(由于实现涉及某种共识算法),但它仍然比简单循环快。它为您提供了ACID属性,这可能是我们最需要的。想想使用循环的情况,如果其中一个更新失败,您如何处理失败?是否可以回滚所有更改而不会引起某些竞争状况?更新是幂等的吗?这实际上取决于您应用因果关系的性质。小心点。

另一种选择是使用线程池来完成网络I / O工作,这肯定可以节省很多时间,但是它也有同样的故障和回滚问题。

答案 3 :(得分:0)

您可以使用TransactWriteItems操作来更新DynamoDB表中的多个记录。

here提供了官方文档,您还可以看到TransactWriteItems javascript / nodejs示例here