amazon-web-services - 在将数据添加到 DynamoDB 之前检查数据是否有效的最佳方法是什么
问题描述
据我了解,Dynamo 中没有外键约束。
我们有用户、组。
由于用户和组彼此紧密相连,因此在此特定用例中它们被存储在同一个表中。但一般来说,它可以归因于同一张表或不同的表。
外汇:
将用户添加到具有给定 groupId 的组的请求。
将站点添加到组的请求。
检查我们将添加给用户的给定 groupId 是否确实存在的最佳和优化方法是什么。对于需要添加到给定组的具有给定 siteId 的站点也是如此。
在将数据插入数据库之前,我们是否会为每个此类字段发送一个 checkIfExists dynamoDB 查询?这听起来未经优化且丑陋。如何以更好的方式解决这个问题?
解决方案
您可以使用事务来执行此操作,这是 Python 中的示例:
import boto3
import botocore.exceptions
TABLE_NAME = "transaction"
def create_table():
ddb = boto3.client("dynamodb")
ddb.create_table(
AttributeDefinitions=[
{"AttributeName": "PK", "AttributeType": "S"},
{"AttributeName": "SK", "AttributeType": "S"},
],
TableName=TABLE_NAME,
KeySchema=[{"AttributeName": "PK", "KeyType": "HASH"}, \
{"AttributeName": "SK", "KeyType": "RANGE"}],
BillingMode="PAY_PER_REQUEST",
)
def add_group(group_name: str):
item = {
"PK": f"G#{group_name}",
"SK": "META",
"groupName": group_name
}
boto3.resource("dynamodb").Table(TABLE_NAME).put_item(Item=item)
def add_user_to_group(user_name: str, group_name: str):
print(f"Attempting to add user {user_name} to group {group_name}")
membership_item = {
"PK": {"S": f"G#{group_name}"},
"SK": {"S": f"U#{user_name}"}
}
client = boto3.client("dynamodb")
try:
client.transact_write_items(
TransactItems=[
{
"ConditionCheck": {
"TableName": TABLE_NAME,
# Check if an item with this key exists
"Key": {
"PK": {"S": f"G#{group_name}"},
"SK": {"S": "META"}
},
"ConditionExpression": "attribute_exists(PK)"
}
},
{
"Put": {
"Item": membership_item,
"TableName": TABLE_NAME
}
}
]
)
except botocore.exceptions.ClientError:
return f"Group {group_name} doesn't exist!"
return f"Added user {user_name} to group {group_name}"
if __name__ == "__main__":
create_table()
add_group("dummy")
print(add_user_to_group("test", "dummy"))
print(add_user_to_group("test", "does_not_exist"))
基本上,您创建一个包含两个项目的事务:
- ConditionCheck 测试组是否存在
- 放置/更新以创建您的会员资格
如果您运行代码,它将创建一个表,添加一个组,然后尝试将用户添加到该组。那行得通,然后它将用户添加到另一个不存在的组中,但失败了。
输出:
Attempting to add user test to group dummy
Added user test to group dummy
Attempting to add user test to group does_not_exist
Group does_not_exist doesn't exist!
推荐阅读
- java - 当我尝试执行 getaccountnumber 方法时,出现图像中提到的以下错误
- c++ - 自动输入别名
- javascript - 如何通过 youtube-dl 接收的数据在客户端创建视频文件?
- sql-server - SQLServer 过滤索引问题
- swift - swift上的简单TCP监听器
- node.js - 在弹性搜索中的映射上获取“在字段 [loc2]”} 上声明的类型 [{default=Point, es_type=nested, type=string}] 没有处理程序
- ruby-on-rails - 带有 where() 条件的 Rails 5 左外连接从左表中排除行
- tomcat - 在 grails-2.2.1 中找不到默认容器
- python - 比较列不同的数据框
- nginx - 在 nginx 位置共享变量