首页 > 解决方案 > 查询和更新 dynamoDb 的最有效方法

问题描述

我有一个发电机数据库表,它将用于存储失败的请求,稍后另一个 lambda 将要读取请求并重新处理它们。

目前我正在使用 typescript CDK 创建这样的表

const myTable = new dynamodb.Table(this, "my-table", {
      tableName: "my-table-name",
      partitionKey: { name: "file_id", type: dynamodb.AttributeType.STRING },
    });

我在 python lambda 中将数据发送到这样的表中

dynamodb = boto3.resource("dynamodb", region_name=region)
my_table = dynamodb.Table("my-table-name")

failedRecord = {
        "file_id": str(file_id),
        "processed": "false",
        "payload": str(payload),
    }

    my_table.put_item(Item=failedRecord)

现在我想从另一个 lambda 中对表中的所有条目进行处理 = false 我想读取它们,对它们做一些事情,然后更新它们的处理 = true。

我是否需要在此处添加二级索引才能提高效率。如何做到这一点的一个例子会很棒。

谢谢

标签: pythonamazon-web-servicesnosqlamazon-dynamodb

解决方案


考虑创建一个仅包含未处理项目的全局二级索引。您可以通过添加/删除 GSI 主键在 GSI 中添加/删除项目。例如,考虑下面的表结构:

在此处输入图像描述

请注意,只有file_id3 和 4 定义了 GSIPK。GSI 在逻辑上看起来像这样:

在此处输入图像描述

DynamoDB 只会将项目投影到该项目上存在 GSIPK 的索引中。您的 lambda 可以从 GSI 读取,做一些工作,将processed属性设置为true并删除GSIPK值。这将有效地从二级索引中删除该项目。

update对 DynamoDB 执行此操作的调用如下所示:

 const params = {
    TableName: YOUR_TABLE_NAME_HERE,
    Key: {
      PK: FILE_ID_HERE
    },
    UpdateExpression: "SET #processed = :true REMOVE #gsipk",
    ExpressionAttributeNames: {
      "#processed": "processed",
      "#gsi1pk": "GSIPK",
    },
    ExpressionAttributeValues: {
      ":true": true
    }
  };

  ddbClient.update(params);

推荐阅读