RTF
RTF

Reputation: 6494

How to insert a map as attribute value when attribute does not yet exist with DynamoDB?

Could someone please tell me how to set a map as a value for an attribute that does not yet exist. I've been trying an update expression "SET MyAttr.#key = :val", but that only works if the attribute exists and if the value of the attribute is already a map.

I tried using "ADD MyAttr.#key = :val" instead, but then I get:

Invalid UpdateExpression: Syntax error; token: "=", near: "#key = :val"

I'm using Java. Note that I'm using an attempting an UpdateItem request to do this. It just occurred to me that maybe this doesn't work with maps. I just assumed it would because I've always been able to have a new item and/or attribute created with an update request if doesn't already exist (with other attribute value data types like string, number etc).

Upvotes: 0

Views: 3664

Answers (1)

Tom Melo
Tom Melo

Reputation: 1499

Let's assume that we have the following Item in our DynamoDB Table:

{
  "id": "91c2b60d-c428-403c-be42-8657b4f20669",
  "firstName": "John",
  "lastName": "Doe"
}

and we want to add custom attributes that we have in a Map:

Map<String, String> customAttributes = new HashMap<>();
customAttributes.put("age", "21");
customAttributes.put("gender", "Male");

AmazonDynamoDB client = AmazonDynamoDBClientBuilder.standard().build();
DynamoDB dynamodb = new DynamoDB(client);

Table table = dynamodb.getTable("users");
UpdateItemSpec updateItemSpec = new UpdateItemSpec()
          .withPrimaryKey("id", "91c2b60d-c428-403c-be42-8657b4f20669")
          .withUpdateExpression("set #customAttributes = :customAttributes")
          .withNameMap(new NameMap().with("#customAttributes", "customAttributes"))
          .withValueMap(new ValueMap().withMap(":customAttributes", customAttributes))
          .withReturnValues(ReturnValue.ALL_NEW);

UpdateItemOutcome outcome = table.updateItem(updateItemSpec);
System.out.println(outcome.getItem().toJSONPretty());

The result:

{
  "id" : "91c2b60d-c428-403c-be42-8657b4f20669",
  "firstName" : "John",
  "lastName" : "Doe",
  "customAttributes" : {
    "gender" : "Male",
    "age" : "21"
  }

}

Now, if we want to add a new attribute to the customAttributes map:

UpdateItemSpec updateItemSpec = new UpdateItemSpec()
    .withPrimaryKey("id", "91c2b60d-c428-403c-be42-8657b4f20669")
    .withUpdateExpression("set customAttributes.#occupation = :value")
    .withNameMap(new NameMap().with("#occupation", "occupation"))
    .withValueMap(new ValueMap().withString(":value", "Programmer"))
    .withReturnValues(ReturnValue.ALL_NEW);

UpdateItemOutcome outcome = table.updateItem(updateItemSpec);

System.out.println(outcome.getItem().toJSONPretty());

I suggest that you take a look at: DynamoDBMapper, it will save you tons of lines of code.

Upvotes: 2

Related Questions