web-dev-qa-db-fra.com

Est-il possible de changer la valeur de la clé Range dans la table DynamoDB?

Je sais que c’est peut-être une question très stupide, mais DynamoDB est nouveau pour moi.

Mon doute est-il possible de mettre à jour la valeur d'une clé Range dans DynamoDB.

Supposons que ma table soit "TEST"

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

Je veux modifier l'attribut Date.

Les valeurs initiales dans le tableau étaient:

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

Exécuter ce code ci-dessous. Je suis capable de changer l'attribut Name qui est GSI.

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);

Mais quand je change de ligne

item1.put("Name", update);

avec

 item1.put("Date", update);

Je reçois une erreur comme

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)

Donc, est-il possible de changer la valeur de la plage clé?

16
Geek_To_Learn

Non, comme le message d'exception l'indique, vous Cannot update attribute Date. This attribute is part of the key.

Vous pouvez également le voir sous la documentation AttributeUpdates :

Les noms des attributs à modifier, l'action à effectuer sur chacun d'eux, Et la nouvelle valeur pour chacun. Si vous mettez à jour un attribut qui est Un attribut de clé d'index pour tous les index de cette table, le type d'attribut Doit correspondre au type de clé d'index défini dans AttributesDefinition De la table. la description. Vous pouvez utiliser UpdateItem pour mettre à jour les attributs non-clés .

La documentation indique que vous pouvez mettre à jour n'importe quel attribut pour "un attribut qui est un attribut de clé d'index pour tous les index de cette table", ce qui signifie que lorsque vous mettez à jour un attribut projeté sur un index, il fait même partie de cet index. clé, cet index sera également mis à jour pour refléter l'élément d'origine.

10
mkobit

À partir de la documentation de AttributeValueUpdate

Vous ne pouvez pas utiliser UpdateItem pour mettre à jour des attributs de clé primaire. Vous devrez plutôt supprimer l'élément, puis utiliser PutItem pour Créer un nouvel élément avec de nouveaux attributs.

9
mbo

Il est un peu enfoui, mais dans la documentation de UpdateItem il indique: "Vous pouvez utiliser UpdateItem pour mettre à jour tous les attributs autres que des clés."

Donc, actuellement, le seul moyen de mettre à jour la clé primaire d’un élément est de supprimer l’ancien article et d’en écrire un nouveau.

3
Johnny Wu

Voici ma mise en œuvre de la mise à jour id dans .net en supprimant l'élément, puis en le recréant avec le nouvel identifiant. Je suppose que Java est très similaire:

 // 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("************************************************");
    }
}

Pour l'appeler, procédez comme suit:

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