【问题标题】:how to group AWS dynamodb table and get latest value of partition key using boto3(lambda)?如何使用 boto3(lambda) 对 AWS dynamodb 表进行分组并获取分区键的最新值?
【发布时间】:2022-11-20 07:09:55
【问题描述】:

我是 AWS dynamodb、lambda 的新手。我对 RDB(MySQL) 有很好的了解。

这是我的示例表

partitian key   sort key    attribute
Device  TimeStamp   REMARKS
D1  2022-12-12 12:13:14 hello
D1  2022-12-12 12:14:14 testing
D2  2022-12-12 12:18:14 hello
D2  2022-12-12 12:19:14 testing
D3  2022-11-12 12:13:14 hello
D3  2022-12-12 12:14:14 testing

我想使用查询语句在 lambda 函数中使用 python boto3 提取以下输出。

每个分区键的最新时间戳值' 输出

D1  2022-12-12 12:14:14 testing
D2  2022-12-12 12:19:14 testing
D3  2022-12-12 12:14:14 testing

请只做那些需要的。先感谢您

约翰逊

我尝试使用 aws lambda 教程,但我可以使用扫描方法获取所有数据

【问题讨论】:

  • 看起来它只是带有 GROUP BY 的 MAX()。计算出语法细节后,请在此处发布您的代码作为答案。 stackoverflow.com/help/self-answer
  • 您是否事先知道所有设备 ID(分区键)?

标签: python aws-lambda amazon-dynamodb boto3


【解决方案1】:

为此,您需要为每个设备发出一个Query,并设置ScanIndexForward=FalseLimit=1

但是,例如,如果您需要所有设备的最新信息,则需要您创建一个全球二级索引 (GSI)。它还要求您为每个设备保留一个“元”记录,这将是最新的项目。

partitian key sort key attribute Meta
Device TimeStamp REMARKS Meta
D1 2022-12-12 12:13:14 hello
D1 2022-12-12 12:14:14 testing
D1 2022-12-12 12:14:14 testing D1_latest
D2 2022-12-12 12:18:14 hello
D2 2022-12-12 12:19:14 testing
D2 2022-12-12 12:19:14 testing D2_latest
D3 2022-11-12 12:13:14 hello
D3 2022-12-12 12:14:14 testing
D3 2022-12-12 12:14:14 testing D3_latest

现在,您的 GSI 将具有 Meta 的分区键,并且将仅保存您需要的信息:

partitian key sort key attribute Meta
Device TimeStamp REMARKS Meta
D1 2022-12-12 12:14:14 testing D1_latest
D2 2022-12-12 12:19:14 testing D2_latest
D3 2022-12-12 12:14:14 testing D3_latest

这将使您能够高效地ScanGSI 获取您需要的物品。但是,它需要您的写入才能使用事务。对于您添加的每个最新设备,您还需要更新元数据项,以便 GSI 也更新为最新值。

【讨论】:

  • 您还必须从不再是最新的项目中删除 *_latest 标志,对吧,这会很麻烦,尤其是在同时对同一设备进行大量写入的情况下。
  • 不,我称之为“元”项目的 _latest 项目将始终是您最新项目的副本。这就是为什么您必须使用事务进行写入,一个用于添加新项,一个用于更新元项。
  • 对于基表中不能有两个具有相同主键的项目这一事实,您打算怎么办?
【解决方案2】:

使用像 Lee 建议的 GSI 是在您想要批量检索与特定特征匹配的项目的情况下采用的一般方法。您在属性中标记具有该特征的项,并将该属性用作 GSI 分区键。然后对 GSI 进行预过滤。

在这种情况下,我认为这有点棘手,因为当一个项目获得特性(最新的)时,另一个必须失去它(不再是最新的),如果您同时有很多潜在的写入,这需要两次写入和这两者之间的协调相同的项目集合。正如 Lee 所说,您可能想要使用事务,这意味着 2 次写入的成本是 2 倍 = 4 个 WCU。

还有别的办法吗?在这种情况下的最佳选择取决于您未指定的细节。一件物品有多大?他们多久更新一次?多个客户端同时写入同一个项目集合的频率是多少?您多久进行一次批量查询?您的规模是否以成本为重,或者成本微不足道并且您想要优化以简化操作? (我希望关于 DynamoDB 的每个 StackOverflow 问题都包括这些事实!)

一种可行的设计(如果项目数据往往很小,并且您希望以更高的读取成本为代价来降低写入成本)是仅将一组值存储在单个项目中。您可以通过直接附加到数组来安全地添加新值(只要数据集保持在 1 KB 以下,这将仅花费 1 个写入单元,如果是 1-2 KB,则花费 2 个写入单元,等等)。因此,与更新事务中的两个项目相比,写入成本节省了 4 倍。然后您可以扫描表格,对于每个项目,让客户端从数组中拉出最后一个项目。扫描将返回更多数据,因此批量读取的成本会更高一些。这就是设计选择取决于用途的原因。

如果我们假设您想要存储每个项目的最后 N 个数据值,那么这是一个特别好的方法,因为否则您必须插入、删除旧的最新标志并删除最旧的记录。在这里,您将读取项目、根据需要更改数组、编写新版本并使用乐观锁定来处理并发。 1 个 WCU 而不是 3 个,或者实际上是 6 个(如果必须使用事务)。

换句话说:“这取决于”

【讨论】:

    猜你喜欢
    • 2023-01-25
    • 1970-01-01
    • 2018-12-16
    • 1970-01-01
    • 2020-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多