簡體   English   中英

如何一次更新 DynamoDB 表中的多個項目

[英]How to update multiple items in a DynamoDB table at once

我正在使用 DynamoDB,我需要更新多條記錄的特定屬性。 用偽語言編寫我的要求我想做一個更新,說“更新表人員設置 relationshipStatus = 'married' where personKey IN (key1, key2, key3, ...)”(假設 personKey 是我的 KEY DynamoDB 表)。

換句話說,我想使用 IN 子句進行更新,或者我想可以將其稱為批量更新。 我發現鏈接明確詢問是否存在像批量更新這樣的操作,而答案是不存在。 但是,它沒有提到 IN 子句。 文檔顯示 ConditionalExpressions 支持 IN 子句(一次可以提供 100 個值)。 但是,我不確定這樣的 IN 子句是否適合我的情況,因為我仍然需要提供一個強制性的 KEY 屬性(它似乎需要一個單一的值——我可能是錯的)並且我擔心它會做每次更新全表掃描。

所以我的問題是:如何同時更新多個 DynamoDB 記錄? 目前看來我將不得不為每個鍵一個一個地調用一個更新語句,這感覺真的很不對……

正如您所指出的,DynamoDB 不支持批量更新操作。 您需要查詢並獲取要更新的所有記錄的鍵。 然后遍歷該列表,一次更新每個項目。

您可以使用 TransactWriteItems 操作更新 DynamoDB 表中的多個記錄。

提供的官方文檔在這里,還可以看到TransactWriteItems的JavaScript /例子的NodeJS 這里

我不知道自從給出答案后它是否發生了變化,但現在有可能

查看文檔: 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

如果您使用 dynogels(由於 dynogels 支持,您不能混合它們,但您可以做的是更新(使用 create 因為在幕后它會像 put 一樣轉換為 batchWrite 函數)

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 限制( 來自文檔):

BatchWriteItem 操作在一個或多個表中放置或刪除多個項目。 對 BatchWriteItem 的單個調用最多可以寫入 16 MB 的數據,其中可以包含多達 25 個放置或刪除請求。 要寫入的單個項目可以大到 400 KB。

如果我沒記錯的話,我認為 dynogels 在發送請求之前將請求分塊到 25 個卡盤中,然后將它們收集在一個承諾中並返回(盡管我不是 100% 確定這一點) - 否則包裝函數將非常容易組裝

DynamoDb 並非設計為支持本機事務的關系數據庫。 最好設計schema,首先避免多次更新的情況。 或者如果它在您的情況下不切實際,請記住您可以在重新設計時改進它。

同時更新多個項目的唯一方法是使用 DynamoDB 提供的 TransactionWrite 操作。 但它有一個限制(例如最多 25 個)。 所以請記住這一點,您可能也應該在您的應用程序中做一些限制。 盡管成本非常高(因為實現涉及一些共識算法),但它仍然比簡單的循環快得多。 它為您提供了 ACID 屬性,這可能是我們最需要的。 想想使用循環的情況,如果其中一個更新失敗,您如何處理失敗? 是否可以回滾所有更改而不會導致某些競爭條件? 更新是冪等的嗎? 這實際上取決於您對原因的應用的性質。 當心。

另一種選擇是使用線程池來做網絡 I/O 工作,這肯定可以節省大量時間,但它也有同樣的故障和回滾問題需要考慮。

您可以按如下方式更新 aws dynamo 表中的多個項目。 假設您有一個包含 2 列的表

|列名| 第二列名|
| 列值 | 列值 |

Aws::String updateExpression("SET #columnA = :valueA, #columnB = :valueB");
updateItemRequest.SetUpdateExpression(updateExpression);

expressionAttributeNames["#columnA"] = "FirstColumnName";
expressionAttributeNames["#columnB"] = "SecondColumnName";

TArray<Aws::DynamoDB::Model::AttributeValue> attributeValues;
Aws::DynamoDB::Model::AttributeValue avColumn1;
avColumn1.SetS("ColumnValue1")
attributeValues.Add(avColumn1);

Aws::DynamoDB::Model::AttributeValue avColumn2;
avColumn2.SetS("ColumnValue2")
attributeValues.Add(avColumn2);

Aws::Map<Aws::String, Aws::DynamoDB::Model::AttributeValue> expressionAttributeValues;
expressionAttributeValues[":valueA"] = avColumn1;
expressionAttributeValues[":valueB"] = avColumn2;
const Aws::DynamoDB::Model::UpdateItemOutcome& result = Client->UpdateItem(updateItemRequest);
if (!result.IsSuccess())
{
    // sad face
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM