如何使用 ConditionExpression 检查非键属性是否已存在于 dynamodb 中?
how to check if non-key attribute already exists in dynamodb using ConditionExpression?
我想插入用户 table 仅当用户 ID、电子邮件和用户名不存在时(希望它们是唯一的)。
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
但它每次都会插入 table,即使用户名或电子邮件已经存在于数据库中。
(我给了新的 userIdNext 作为它是主键,不能重复 )
我正在使用 Python 实现 boto3
dynamodb 只能为散列范围 table 键(而不是全局二级索引键)强制唯一性
在您的情况下,有 2 个选项:
1) 在应用程序级别强制执行 - 查询记录,并查找是否重复
2) 添加另一个具有 hash/range 值的 dynamodb table(可以强制唯一性),您可以在将项目放入主 table 之前查询此 table
3) 使用应用程序锁 (memcache..)
4) 不要使用 dynamodb(可能无法满足您的要求)
在此处向您推荐答案:
好的,我在我的应用程序中发现了错误。
我尝试向 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, can you put a sample of your code that do this? "i have
Global Secondary Indexes to check if username or emails exists
already, but its not atomic. So if 2 users query at the same time and
get that email1 is available, they both insert into users table. And
if there is no check to verify if email/username does not exist
already, we have duplicate entries for email/username "
我想插入用户 table 仅当用户 ID、电子邮件和用户名不存在时(希望它们是唯一的)。
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
但它每次都会插入 table,即使用户名或电子邮件已经存在于数据库中。
(我给了新的 userIdNext 作为它是主键,不能重复 )
我正在使用 Python 实现 boto3
dynamodb 只能为散列范围 table 键(而不是全局二级索引键)强制唯一性
在您的情况下,有 2 个选项:
1) 在应用程序级别强制执行 - 查询记录,并查找是否重复
2) 添加另一个具有 hash/range 值的 dynamodb table(可以强制唯一性),您可以在将项目放入主 table 之前查询此 table
3) 使用应用程序锁 (memcache..)
4) 不要使用 dynamodb(可能无法满足您的要求)
在此处向您推荐答案:
好的,我在我的应用程序中发现了错误。
我尝试向 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, can you put a sample of your code that do this? "i have Global Secondary Indexes to check if username or emails exists already, but its not atomic. So if 2 users query at the same time and get that email1 is available, they both insert into users table. And if there is no check to verify if email/username does not exist already, we have duplicate entries for email/username "