Reputation: 13
I'm trying to use a condition to put a intem on DynamoDB, but doesn't work.
I have a table of users and a attribute id as primary key and attibute name must be unique.
conditions := aws.String("NOT contains(email, :e_email)")
attributes := map[string]*dynamodb.AttributeValue{
":e_mail": &dynamodb.AttributeValue{
S: &user.Email,
},
}
input := &dynamodb.PutItemInput{
Item: item,
TableName: dynamoTable,
ConditionExpression: conditions,
ExpressionAttributeValues: attributes,
}
_, err = dynamo.PutItemWithContext(ctx1, input)
if err != nil {
if erro, ok := err.(awserr.Error); ok {
if erro.Code() == dynamodb.ErrCodeConditionalCheckFailedException {
log.Println("User already exists")
body, _ := json.Marshal(models.ErrUsuarioJaExiste)
resp.StatusCode = models.ErrUsuarioJaExiste.CodigoHTTP
resp.Body = string(body)
return resp
}
}
log.Println(err)
resp.StatusCode = models.ErrInterno.CodigoHTTP
body, _ := json.Marshal(models.ErrInterno)
resp.Body = string(body)
return resp
}
But I still can add items with the same email
Upvotes: 1
Views: 5080
Reputation: 78663
That's not how conditional expressions work. DynamoDB is not testing all items in the table for a matching email. It's testing this item for a matching email. Your conditional expression is only being applied to the item whose ID you are actually presenting on the put call, if there is such an item.
Remember that PutItem can be used to insert a new item, but it can also be used to replace existing items. If an item with that ID is absent, which I presume is indeed the case here because you're writing a new ID, then your conditional expression will never work.
Make email a primary key then you can use a conditional expression to test for presence and reject duplicate email insertion. Use the attribute_not_exists function with the name of the email attribute.
To read more on this topic, see Confirming existence or non-existence of an item.
Upvotes: 6