【问题标题】:Is It possible to change value of Range key in DynamoDB Table?是否可以更改 DynamoDB 表中 Range 键的值?
【发布时间】:2015-05-18 06:57:04
【问题描述】:

我知道这可能是一个非常愚蠢的问题,但我是 DynamoDB 的新手。

我怀疑是否可以在 DynamoDB 中更新 Range Key 的值。

假设我的表是“TEST”

{
ID : PK/HK
Date : RK
Name : GSI 
Add : LSI
}

我要修改Date属性。

表中的初始值为:

{
ID = "344"
Date = "5656"
Name = "ABC"
}

在下面运行此代码。我可以更改 GSI 的 Name 属性。

Map<String,AttributeValue> item = new HashMap<String,AttributeValue>();
item.put("ID", new AttributeValue("344"));
item.put("Date", new AttributeValue("5656"));

Map<String,AttributeValueUpdate> item1 = new HashMap<String,AttributeValueUpdate>();

AttributeValueUpdate update = new AttributeValueUpdate().withValue(new AttributeValue("AMIT")).withAction("PUT");
item1.put("Name", update);


UpdateItemRequest updateItemreq = new UpdateItemRequest("Test",item,item1);
UpdateItemResult updateItemres = dynamoDBUSEast.updateItem(updateItemreq);

但是当我改变这一行时

item1.put("Name", update);

 item1.put("Date", update);

我遇到了一些错误

Exception in thread "main" com.amazonaws.AmazonServiceException: One or more parameter values were invalid: Cannot update attribute Date. This attribute is part of the key (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ValidationException; Request ID: HRRP24Q7C48AMD8ASAI992L6MBVV4KQNSO5AEMVJF66Q9ASUAAJG)
    at com.amazonaws.http.AmazonHttpClient.handleErrorResponse(AmazonHttpClient.java:820)
    at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:439)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:245)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.invoke(AmazonDynamoDBClient.java:2908)
    at com.amazonaws.services.dynamodbv2.AmazonDynamoDBClient.updateItem(AmazonDynamoDBClient.java:1256)

那么是否可以更改范围键值?

【问题讨论】:

  • 无法更改其唯一键

标签: java amazon-dynamodb


【解决方案1】:

不,就像异常消息所述,你 Cannot update attribute Date. This attribute is part of the key

你也可以在AttributeUpdates documentation下面看到这个:

要修改的属性的名称,要对每个属性执行的操作, 以及每个的新值。如果您要更新的属性是 该表上任何索引的索引键属性,该属性 type 必须与 AttributesDefinition 中定义的索引键类型匹配 的表说明。 您可以使用 UpdateItem 更新任何非键 属性。

文档声明您可以更新“作为该表上任何索引的索引键属性的属性”的任何属性,这意味着当您更新投影到索引上的属性时,即使它是一部分在该索引键中,该索引也将被更新以反映原始项目。

【讨论】:

    【解决方案2】:

    来自AttributeValueUpdate的文档

    您不能使用 UpdateItem 来更新任何主键属性。 相反,您需要删除该项目,然后使用 PutItem 创建具有新属性的新项目。

    【讨论】:

      【解决方案3】:

      它有点隐藏,但在UpdateItem 的文档中它说: “您可以使用 UpdateItem 来更新任何非关键属性。”

      所以,目前更新一个项目的主键的唯一方法是删除旧项目并写入一个新项目。

      【讨论】:

        【解决方案4】:

        这是我在 .net 中通过删除项目然后使用新 id 重新创建它来更新 id 的实现。我假设 java 非常相似:

         // Based on https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/LowLevelDotNetItemsExample.html
        public class UpdateId
        {
            private static string tableName = "MyTableName";
            private static AmazonDynamoDBClient client = new AmazonDynamoDBClient();
            private static bool isVerbose = false;
        
            public static void ChangeId(string currentId, string newId)
            {
                try
                {
                    var deletedItem = DeleteItem(currentId);
        
                    if (deletedItem.Count == 0)
                    {
                        Console.WriteLine($"ERROR: Item to delete not found: {currentId}");
                        return;
                    }
                    deletedItem["Id"] = new AttributeValue
                    {
                        S = newId
                    };
        
                    CreateItem(deletedItem);
                    var updatedItem = RetrieveItem(newId);
                    if (updatedItem.Count > 0 && updatedItem["Id"].S == newId)
                    {
                        Console.WriteLine($"Item id successfully changed from ({currentId}) to ({newId})");
                    }
                    else
                    {
                        Console.WriteLine($"ERROR: Item id didn't change from ({currentId}) to ({newId})");
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.Message);
                    Console.WriteLine("To continue, press Enter");
                    Console.ReadLine();
                }
            }
        
            private static void CreateItem(Dictionary<string, AttributeValue> item)
            {
                var request = new PutItemRequest
                {
                    TableName = tableName,
                    Item = item
                };
                client.PutItem(request);
            }
        
            private static Dictionary<string, AttributeValue> RetrieveItem(string id)
            {
                var request = new GetItemRequest
                {
                    TableName = tableName,
                    Key = new Dictionary<string, AttributeValue>()
                {
                    { "Id", new AttributeValue {
                          S = id
                      } }
                },
                    ConsistentRead = true
                };
                var response = client.GetItem(request);
        
                // Check the response.
                var attributeList = response.Item; // attribute list in the response.
                if (isVerbose)
                {
                    Console.WriteLine("\nPrinting item after retrieving it ............");
                    PrintItem(attributeList);
                }
                return attributeList;
        
            }
        
            private static Dictionary<string, AttributeValue> DeleteItem(string id)
            {
                var request = new DeleteItemRequest
                {
                    TableName = tableName,
                    Key = new Dictionary<string, AttributeValue>()
                {
                    { "Id", new AttributeValue {
                          S = id
                      } }
                },
        
                    // Return the entire item as it appeared before the update.
                    ReturnValues = "ALL_OLD",
              //      ExpressionAttributeNames = new Dictionary<string, string>()
              //  {
              //      {"#IP", "InPublication"}
              //  },
              //      ExpressionAttributeValues = new Dictionary<string, AttributeValue>()
              //  {
              //      {":inpub",new AttributeValue {
              //           BOOL = false
              //       }}
              //  },
              //      ConditionExpression = "#IP = :inpub"
                };
        
                var response = client.DeleteItem(request);
        
                // Check the response.
                var attributeList = response.Attributes; // Attribute list in the response.
                                                         // Print item.
                if (isVerbose)
                {
                    Console.WriteLine("\nPrinting item that was just deleted ............");
                    PrintItem(attributeList);
                }
        
                return attributeList;
            }
        
            private static void PrintItem(Dictionary<string, AttributeValue> attributeList)
            {
                foreach (KeyValuePair<string, AttributeValue> kvp in attributeList)
                {
                    string attributeName = kvp.Key;
                    AttributeValue value = kvp.Value;
        
                    Console.WriteLine(
                        attributeName + " " +
                        (value.S == null ? "" : "S=[" + value.S + "]") +
                        (value.N == null ? "" : "N=[" + value.N + "]") +
                        (value.SS == null ? "" : "SS=[" + string.Join(",", value.SS.ToArray()) + "]") +
                        (value.NS == null ? "" : "NS=[" + string.Join(",", value.NS.ToArray()) + "]")
                        );
                }
                Console.WriteLine("************************************************");
            }
        }
        

        要调用它,只需这样做:

        UpdateId.ChangeId("OriginalId", "NewId");
        

        【讨论】:

          猜你喜欢
          • 2019-10-31
          • 1970-01-01
          • 2016-10-17
          • 1970-01-01
          • 1970-01-01
          • 2018-10-06
          • 1970-01-01
          • 2014-10-16
          • 1970-01-01
          相关资源
          最近更新 更多