如何使用 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 "