aws-sdk-js: Dyanmodb.update to delete entry from StringSet does not work

Confirm by changing [ ] to [x] below to ensure that it’s a bug:

Describe the bug Can not delete a entry from string set using DELETE operation.

Is the issue in the browser/Node.js? Node.js

If on Node.js, are you running this on AWS Lambda?

Details of the browser/Node.js version 10.17.0

SDK version number 2.580.0

To Reproduce (observed behavior) Steps to reproduce the behavior (please share code or minimal repo)

  1. Create StringSet and put some data in it.
  2. Delete entry from Set (error) Invalid UpdateExpression: Incorrect operand type for operator or function; operator: DELETE, operand type: MAP"

problem code.

const dynamoDb = new AWS.DynamoDB.DocumentClient();
  const resp = await dynamoDb.scan({
    TableName: TABLE_NAME,
    FilterExpression: 'attribute_exists(Cids)',
  }).promise();
  console.info(`Update ${resp.Count} users`);

  for (const item of resp.Items || []) {
    console.info(item.Uid);
    await dynamoDb.update({
      TableName: TABLE_NAME,
      Key: {
        Uid: { S: item.Uid },
      },
      UpdateExpression: 'DELETE Cids :cameraId',
      ReturnValues: 'ALL_NEW',
      ExpressionAttributeValues: {
        ':cameraId': { SS: [id] },
      }
    }).promise();
  }

but same operation in python and CLI works.

Expected behavior Delete the entry from string set.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 3
  • Comments: 17 (3 by maintainers)

Most upvoted comments

const dynamoDb = new AWS.DynamoDB.DocumentClient({region: 'ap-northeast-2'});
  const resp = await dynamoDb.scan({
    TableName: TABLE_NAME,
    FilterExpression: 'attribute_exists(Cids)',
  }).promise();
  console.info(`Update ${resp.Count} users`);

  for (const item of resp.Items || []) {
    console.info(item.Uid);
    await dynamoDb.update({
      TableName: TABLE_NAME,
      Key: {
        Uid: item.Uid,
      },
      UpdateExpression: 'DELETE Cids :cameraId',
      ReturnValues: 'ALL_NEW',
      ExpressionAttributeValues: {
        ':cameraId': dynamodb.createSet([id]),
      }
    }).promise();
  }

DocumentClient.createSet() works.

or

const AWS = require('aws-sdk');                                                    
const dynamoDb = new AWS.DynamoDB({region: 'ap-northeast-2'});                     
dynamoDb.updateItem({                                                              
  TableName: 'test',                                                               
  Key: {                                                                           
    Uid: { S: 'id1'},                                                          
  },                                                                               
  UpdateExpression: 'ADD Cids :cameraId',                                          
  ExpressionAttributeValues: {                                                     
    ':cameraId': { SS: ['cid3'] },                                               
  }                                                                                
}, (err, data) => {                                                                
  if (err) console.log(err);                                                       
  else console.log(data);                                                          
})

no DocumentClient version works too.

The only workaround possible for me here was not to use a DELETE operation, instead, you gotta query the item, find the index in the array you wish to delete, and remove it a REMOVE operation:

like in this case, arrayField contains an array of Users, and I want to delete by user’s phoneNumber.

const dataStore = await dynamodb.get(queryParams).promise(); let i=0; //save the index for(i = 0; i < dataStore.Item.myTable.length; i++){ if(dataStore.Item.arrayField[i].phone === phoneNumber) { break; } }

//extracted from for loop for clarity

if(i < dataStore.Item.arrayField.length){
    const updateStoreParams = {
        TableName: tableName,
        Key: storeTableKey,
        UpdateExpression: `REMOVE arrayField[${i}]`,
    }
    await dynamodb.update(updateStoreParams).promise().catch((err) => {
        console.log(err);
        throw err;
        });
}

.net dev celerino herrera g https://chamizo.pro/contact

On Fri, Apr 30, 2021 at 1:06 PM Paulo Fagiani @.***> wrote:

@haandol https://github.com/haandol @ajredniwja https://github.com/ajredniwja I’ve been facing a similar issue and I’ve posted its details in this Stack Overflow https://stackoverflow.com/questions/67338331/updating-dynamodb-record-with-delete-set-on-updateexpression-fails-with-node-js .

It is odd because if i use ADD it works but not DELETE…

The error is:

ERROR Invoke Error { “errorType”:“Error”, “errorMessage”:“ValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function; operator: DELETE, operand type: NUMBER, typeSet: ALLOWED_FOR_DELETE_OPERAND”, “stack”:[…] }

Would you suggest any workarounds while this gets fixed?

I really appreciate any insights towards this.

Keep Rocking!

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/aws/aws-sdk-js/issues/3025#issuecomment-830351372, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAWDXZBL4OCPKKKBYJ2NAW3TLMEUTANCNFSM4J65GDGA .