我想仅在userId,email和username不存在时才插入users表(希望这些是唯一的)。
userId是主键(哈希键,数据类型 - 数字)。
用户名和电子邮件是非关键属性(两个字符串)。
以下是我的尝试:
response = userTable.put_item(
Item={
'userId': userIdNext,
'accType': 0,
'username': usernameInput,
'pwd': hashedPwd,
'email': emailInput
},
ConditionExpression = "(attribute_not_exists(userIdNext)) AND (NOT (contains (email, :v_email))) AND (NOT (contains(username, :v_username)))",
ExpressionAttributeValues={
":v_email": emailInput,
":v_username": usernameInput
}
)
我尝试从这里跟踪逻辑运算符和条件表达式的aws文档:AWS Conditional Expressions
但即使用户名或电子邮件已经存在于数据库中,它也会每次都插入到表中。
(我给新的userIdNext,因为它是主键,不能重复)< / p>
我正在使用Python实现 boto3
答案 0 :(得分:4)
dynamodb只能对哈希范围表键强制唯一性(而不是全局二级索引键)
在您的情况下有2个选项:
1)强制它在应用程序级别 - 查询记录,并查找是否重复
2)添加另一个带有散列/范围值的dynamodb表(可强制执行uniqeness),您可以在将项目放入主表之前查询此表
3)使用应用程序锁(memcache ..)
4)不要使用dynamodb(也许它不能满足你的要求)
在这里引用你的答案:
答案 1 :(得分:1)
好的,我在申请中发现了这个错误。
我尝试向DynamoDB执行条件置位项,但是我传递了一个与DynamoDB上存在的主键不同的主键,此时将创建一个新对象并忽略条件表达式。
# id primary key
id = 123
# email is only index
email = "email@email.com"
item = {
"id": id,
"email": email
"info": {
"gender": "male",
"country": "Portugal"
}
}
response = self._table.put_item(Item=item, ConditionExpression="email <> :v_email", ExpressionAttributeValues={":v_email": email})
如果您希望条件表达式在DynamoDB put_item上正常工作,您应该发送与DB上存在的主键相同的主键。
kishorer747,你能把你的代码样本做到这一点吗? &#34;我有 全局二级索引,用于检查是否存在用户名或电子邮件 已经,但它不是原子的。因此,如果2个用户同时查询和 获取该email1可用,它们都插入到users表中。和 如果没有检查以验证电子邮件/用户名是否不存在 我们已经有重复的电子邮件/用户名条目&#34;