dynamodb-toolbox
dynamodb-toolbox copied to clipboard
Check why primary/secondary GSIs are using if_not_exists
Is this still a thing with the latest version, i.e. by default you get generated UpdateExpression
like this:
SET #gsi1pk = if_not_exists(#gsi1pk,:gsi1pk), #gsi1sk = if_not_exists(#gsi1sk,:gsi1sk)
I am having this issue with v0.3.5
, and am wondering if this has been addressed in the latest version, where it is straight forward to not have it generated like that, and where you do not have to provide the whole UpdateExpression
yourself either.
Sidenote: I have seen in an issue where they say this is not an issue and the array for composite keys
fixes this, but this won't work for me (besides, I've read in latest documentation that the array for composite keys
is going to be dropped in the future).
For now I am bypassing this issue by providing the UpdateExpression
in the params
object to the query
method, i.e. instead of having this in the expression (which was generated):
... #gsi1sk = if_not_exists(#gsi1sk,:gsi1sk) ...
I replace it with:
... #gsi1sk = :gsi1sk ...
Regards
Hi @kr1p70n1c! The only way the if_not_exists
should be generated is if you set a default
for the attribute. Can you post your Table
and Entity
definitions?
Hi @jeremydaly,
Thank you for your quick response.
I certainly do have a default
defined:
gsi1sk: {
hidden: false,
type: 'string',
default: (data: any) => {
return data.status && data.id ? `ORDERSTATUS#${data.status}#${data.id}` : null;
}
},
I have to update that sort key as it is part of my modeling as I am using the mutable status
as part of an access pattern:
- Get user orders by status
As stated before, I do have it working for now as I am specifying the whole UpdateExpression
, I was just hoping that there would have been an easier way to indicate/override that certain fields should not have the if_not_exists
auto-generated in an UpdateExpression
.
Ah, I see. The point of the if_not_exists
for default
values is so that when an UpdateItem
is called without specifying the value, it'll send the default value in to ensure that newly created items have a default value. This way, if an item exists, then the default
value won't overwrite the existing attribute value in the item.
It looks like you want to set the value (meaning not use the default
functionality) when updating an item. In that case, you should use the transform
property when defining your Entity (see here: https://www.dynamodbtoolbox.com/docs/entity#using-an-object). This will allow you to send the result in as the VALUE, not the DEFAULT. If you return undefined
from the transform
function, then the default
behavior should kick in.
@jeremydaly Ah thanks for the feedback. Just to confirm the version of the library, must I use the latest for this to work or will v0.3.5
do?
I am asking because I am still on v0.3.5
and I have implemented the transform
function as well, and returning the value
from it (and I can confirm that value
is indeed the new value I need it to be), but the UpdateExpression
still generates as:
... #gsi1sk = if_not_exists(#gsi1sk,:gsi1sk) ...
As reference my default
and transform
functions:
default: (data: any) => {
return data.status && data.id ? `ORDERSTATUS#${data.status}#${data.id}` : null;
},
transform: (value: any, data: any) => {
logger.info('gsi1sk - value, data:', value, data);
return value;
}
Do note if I return undefined
from transform
then my items are created with the gsi1sk
field being empty.
Hmm, that's not the way it should work. Check v0.4.X of the library to see if there is a change in behavior, but that shouldn't have been touched. I'll mark this as a bug and make sure it gets addressed.
I tried the latest version (0.4.3) again now, but I still have the issue as I reported in #269
I made an additional comment their now.