Dynamodb中的条件插入

时间:2019-06-14 10:34:19

标签: amazon-dynamodb boto3 python-3.7

我正在创建一个休假跟踪器应用程序,我想在其中存储用户ID以及起始日期和截止日期。我使用Amazon的DynamoDB作为数据库,并且用户通过自定义命令输入请假。 例如:从当前日期起申请离开

我想避免数据库中的重复条目。例如,如果用户已经在06-10-2019到10-10-2019之间申请了休假,并且再次在同一日期之间申请了休假,那么他们应该收到一条消息,说该假已经存在,并且应该有新记录不能为同一对象创建。

但是,一个用户可以申请多张假,而两个用户可以在同一日期之间休假。

我尝试使用以下条件语句:

table.put_item(
            Item={
                'leave_id': leave_id,
                'user_id': user_id,
                'from_date': from_date,
                'to_date': to_date,
            },
            ConditionExpression='attribute_not_exists(user_id) AND attribute_not_exists(from_date) AND attribute_not_exists(to_date)'
        )

其中,leave_id是分区键。但是,这不起作用,并且即使日期相同也每次都会添加新行。我已经浏览过其他类似的问题,但是还无法理解如何正确配置它。

关于我应该如何做的任何想法,或者是否应该遵循其他设计?

1 个答案:

答案 0 :(得分:1)

如果您使用{strong> 尚不存在的leave_id来调用代码,则将始终插入该项目。如果您使用leave_id调用代码,该代码在表中已经存在 ,那么您应该会收到An error occurred (ConditionalCheckFailedException) when calling the PutItem operation: The conditional request failed错误消息。

我有两个建议:

如果您不想更改表,则可以使用user_id作为分区键来创建二级索引,然后在给定用户具有一些from_date的所有项目中查询索引和to_date属性。 像这样:

table.query(
    IndexName='user_id-index',
    KeyConditionExpression=Key('user_id').eq(user_id),
    FilterExpression=Attr('from_date').exists() & Attr('from_date').exists()
)

然后,您将需要检查是否有重叠的请假申请等(例如,请假申请在已完成的请假结束之前开始)。在确定请假请求有效后,您将致电put_item

另一种建议,也许是更好的建议是在您的表上创建一个复合主键,并以user_id作为分区键,以leave_id作为排序键。这样,您可以针对特定用户的所有请假请求执行查询,而无需创建二级索引。