dynogels icon indicating copy to clipboard operation
dynogels copied to clipboard

Docs need updating for Exists condition

Open austin43 opened this issue 5 years ago • 3 comments

Currently, the dynogels docs say you can use: Exists: true as a param, but specifying this without a Value causes dynamo to throw: ExpressionAttributeValues must not be empty.

Per the AWS docs: The default setting for Exists is true. If you supply a Value all by itself, DynamoDB assumes the attribute exists: You don't have to set Exists to true, because it is implied.

DynamoDB returns a ValidationException if: Exists is true but there is no Value to check. (You expect a value to exist, but don't specify what that value is.)

I think we should update the docs to specify this like { email: { Value: '[email protected]'} }.

[email protected]

EDIT

Upon looking deeper at this functionality, it seems the similarities of usage of "Exists" are only coincidental. Looks like manual construction vs. using dynamo ExpectedAttributeValue.

Because an empty object of ExpressionAttributeValues is generated, the aws sdk is complaining. Is this potentially only a factor on newer aws sdk versions?

austin43 avatar Sep 19 '18 18:09 austin43

await MyModel.destroyAsync('Id-123', 'Id-123', { expected: { Id: { Exists: true } } })

generates

  Key: { Id: 'Id-123', EntityId: 'Id-123' },
  ExpressionAttributeNames: { '#EntityId': 'EntityId', '#Id': 'Id' },
  ExpressionAttributeValues: {},
  ConditionExpression: '(attribute_exists(#Id)) AND (attribute_exists(#EntityId))' }

austin43 avatar Sep 19 '18 19:09 austin43

A valid workaround for now is to pass Expected in to the params:


await MyModel.destroyAsync('Id-123', 'Id-123', {
	Expected: {
		Id: {
			Value:'Id-123'
		},
		EntityId: {
			Value: 'Id-123'
		}
	}
})

austin43 avatar Sep 19 '18 19:09 austin43

await MyModel.destroyAsync('Id-123', 'Id-123', { expected: { Id: { Exists: true } } })

generates

  Key: { Id: 'Id-123', EntityId: 'Id-123' },
  ExpressionAttributeNames: { '#EntityId': 'EntityId', '#Id': 'Id' },
  ExpressionAttributeValues: {},
  ConditionExpression: '(attribute_exists(#Id)) AND (attribute_exists(#EntityId))' }

This looks like a valid query to me.

I'm guessing the problem is that ExpressionAttributeValues must either contain at least one attribute or not be passed at all. That is, omitting it should work but passing {} is probably being rejected.

If that's the case, this is a breaking change that DynamoDB and/or aws-sdk made.

Can you write a service-level test that fails?

cdhowie avatar Sep 20 '18 17:09 cdhowie