Skip to content

Instantly share code, notes, and snippets.

@daverickdunn
Last active March 27, 2023 11:45
Show Gist options
  • Save daverickdunn/4c6a0f61a0b969ec59e589353138bdc3 to your computer and use it in GitHub Desktop.
Save daverickdunn/4c6a0f61a0b969ec59e589353138bdc3 to your computer and use it in GitHub Desktop.
DynamoDB - Dynamically Build an Update Expression
const generateUpdateQuery = (fields) => {
let exp = {
UpdateExpression: 'set',
ExpressionAttributeNames: {},
ExpressionAttributeValues: {}
}
Object.entries(fields).forEach(([key, item]) => {
exp.UpdateExpression += ` #${key} = :${key},`;
exp.ExpressionAttributeNames[`#${key}`] = key;
exp.ExpressionAttributeValues[`:${key}`] = item
})
exp.UpdateExpression = exp.UpdateExpression.slice(0, -1);
return exp
}
let data = {
'field' : { 'subfield': 123 },
'other': '456'
}
let expression = generateUpdateQuery(data)
let params = {
// Key, Table, etc..
...expression
}
console.log(params)
@MasonGeloso
Copy link

For single field updates, the trim function doesn't work on line 12. I would recommend changing it to a regex expression like so:

exp.UpdateExpression = exp.UpdateExpression.replace(/(^,)|(,$)/g, "")

@daverickdunn
Copy link
Author

daverickdunn commented Dec 16, 2020

For single field updates, the trim function doesn't work on line 12. I would recommend changing it to a regex expression like so:

exp.UpdateExpression = exp.UpdateExpression.replace(/(^,)|(,$)/g, "")

Hi Mason, thanks for the feedback, however I can't spot the issue you're describing. Can you give an example of a "single field update"? Thanks.

Edit: NM, I see the issue! trim only removes whitespace. I'm not sure where I got the idea that it accepted an argument...

@jericromero
Copy link

jericromero commented May 3, 2021

it works. btw, does it support nested objects?

@daverickdunn
Copy link
Author

daverickdunn commented May 3, 2021

it works. btw, does it support nested objects?

It does not. If you're looking to update nested objects on a regular basis, then I suggest you consider using a different DB.

Edit: To be clear, what I mean is, if you want to update specific nested fields. If you're happy to update entire objects this works fine.

@lentyai2
Copy link

lentyai2 commented Sep 2, 2021

Thanks @daverickdunn! Exactly what I was looking for!

@syerwin
Copy link

syerwin commented Jul 30, 2022

Thanks @daverickdunn .. it saves me a lot

@KMurphs
Copy link

KMurphs commented Dec 13, 2022

This was useful. Thank you very much.
Added a python implementation of the same logic

def generate_update_query(fields):
    exp = {
        "UpdateExpression": 'set',
        "ExpressionAttributeNames": {},
        "ExpressionAttributeValues": {}
    }
    for key, value in fields.items():
        exp["UpdateExpression"] += f" #{key} = :{key},"
        exp["ExpressionAttributeNames"][f"#{key}"] = key
        exp["ExpressionAttributeValues"][f":{key}"] = value
    exp["UpdateExpression"] = exp["UpdateExpression"][0:-1] 
    return exp

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment