go - 具有多个条件的 Dynamo putItem 在 localstack 中不起作用
问题描述
我第一次在本地的玩具项目中直接使用 Dynamo。我正在尝试创建由条件表达式保护的记录-如果用户名(范围键)或 uniqueId(哈希键)已经存在,则失败:"attribute_not_exists(UserId) and attribute_not_exists(Username)"
。但是,当我使用相同的用户名放置记录时,我没有遇到冲突——并且对表的扫描证实了这一点。我正在使用 localstack(本地 AWS 模拟),如果这有所作为。
问题:
- 我应该使用事务还是其他抽象?
- 我在表格设置中构建的键是否错误(见 q 底部)?
- 我需要在条件中指定键的类型吗?
以下是创建记录的逻辑:
userID := GenerateUniqueID()
record := UserCredentialsRecord{
UserID: userID,
Username: username,
Password: base64.StdEncoding.EncodeToString(hashedPassword),
Salt: base64.StdEncoding.EncodeToString(salt),
Email: email,
AccountCreatedTS: time.Now().Unix(),
}
...
input := &dynamodb.PutItemInput{
Item: av,
TableName: aws.String(userCredentialsTableName),
ConditionExpression: aws.String("attribute_not_exists(UserId) and attribute_not_exists(Username)"),
}
...
_, err = session.PutItem(input)
if err != nil {
fmt.Println("Got error calling PutItem:", err.Error())
}
这是 localstack 中的 Dynamo 表:
localstack | ++ aws --endpoint-url=http://localstack:4566 dynamodb create-table --table-name UserCredentials --attribute-definitions AttributeName=UserID,AttributeType=S AttributeName=Username,AttributeType=S --key-schema AttributeName=UserID,KeyType=HASH AttributeName=Username,KeyType=RANGE --provisioned-throughput ReadCapacityUnits=1,WriteCapacityUnits=1
localstack | {
localstack | "TableDescription": {
localstack | "AttributeDefinitions": [
localstack | {
localstack | "AttributeName": "UserID",
localstack | "AttributeType": "S"
localstack | },
localstack | {
localstack | "AttributeName": "Username",
localstack | "AttributeType": "S"
localstack | }
localstack | ],
localstack | "TableName": "UserCredentials",
localstack | "KeySchema": [
localstack | {
localstack | "AttributeName": "UserID",
localstack | "KeyType": "HASH"
localstack | },
localstack | {
localstack | "AttributeName": "Username",
localstack | "KeyType": "RANGE"
localstack | }
localstack | ],
localstack | "TableStatus": "ACTIVE",
localstack | "CreationDateTime": 1610668286.312,
localstack | "ProvisionedThroughput": {
localstack | "LastIncreaseDateTime": 0.0,
localstack | "LastDecreaseDateTime": 0.0,
localstack | "NumberOfDecreasesToday": 0,
localstack | "ReadCapacityUnits": 1,
localstack | "WriteCapacityUnits": 1
localstack | },
localstack | "TableSizeBytes": 0,
localstack | "ItemCount": 0,
localstack | "TableArn": "arn:aws:dynamodb:us-east-1:000000000000:table/UserCredentials"
localstack | }
localstack | }
解决方案
attribute_not_exists
您对条件表达式的作用有误解。
这并不意味着该属性在表中的任何项目上都不存在,而是该属性在您正在使用的项目上不存在。
因此,操作按设计进行。
如果要确保没有两个具有相同用户名或用户 ID 的项目添加到表中,则必须使用这两个属性作为表的主键,或者想出另一种方法来检查重复。
推荐阅读
- angular - 如何在一个数组中结合两个基于 ID 的 observables?
- datatable - 从 pdf 导出中的数据表标题中删除选择选项
- python - 如何将列表混合列表中的数字字符串转换为int(Python)
- java - 无法获取 getter 的值
- python - 您如何在 Flask 中发送滑块值的发布请求?
- python - Apache2上的Django - 进行更改时重新启动服务器?
- python - 如何使用 Django 中的确认码更新电子邮件地址?
- python-3.x - 如何在小端打包十六进制后删除 b 或字节对象前缀?
- firebase - 使用多个 where 子句查询 firestore
- javascript - HTML 文件无法连接到 socketio