我正在尝试使用条件将一个intem放在DynamoDB上,但是不起作用。
我有一个用户表,属性ID作为主键,并且商品名称必须是唯一的。
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
}
但是我仍然可以使用相同的电子邮件添加项目
答案 0 :(得分:0)
您误解了条件表达式的工作方式。 DynamoDB不会测试表中的所有项是否有匹配的电子邮件。它正在测试此项目是否有匹配的电子邮件。如果有这样的项目,则您的条件表达式仅会应用于您实际在其put调用中显示其ID的项目。
请记住,PutItem可用于插入新项目,但也可用于替换现有项目。如果不存在具有该ID的项目,我想在这里确实是这种情况,因为您正在编写一个新ID,那么您的条件表达式将从不起作用。
将电子邮件设为主键,然后您可以使用条件表达式来测试是否存在并拒绝重复的电子邮件插入。将attribute_not_exists函数与电子邮件属性的名称一起使用。