繁体   English   中英

无论键或条件如何,如何更新 DynamoDB 表中的属性?

[英]How can I update an attribute in a DynamoDB table regardless of the key or condition?

我有一个 DynamoDB 表说data 该表有 400k 项。 每个项目有 4 个字段 -

  • id (string) 这是我的分区键
  • 状态(是/否)
  • 添加日期
  • 资源

现在所有项目都有一个status =“Y”。 无论密钥或任何条件如何,如何更新所有项目并将所有 400k 项目的状态设置为“N”?

在 MySQL 中,等效语句为 -

UPDATE data SET status = 'N';

我希望通过命令行或在 python 中使用 boto3 来完成

没有简单或便宜的方法来做你想做的事。 您基本上需要做的是读取写入整个数据库:

  1. 如果您知道单个项目的键,则可以使用UpdateExpression"set status =:N"执行UpdateItem请求。 这只会修改“状态”属性(使 rest 保持不变),但您将产生的成本(或您将使用的预置吞吐量)将是写入整个项目的成本。 所以所有这些操作的总和将是重写整个数据库的成本。
  2. 您应该在上面的UpdateItem中添加一个ConditionExpression ,它只会在项目实际仍然存在时更新项目(您可以在其关键属性上使用attribute_exists()条件来验证项目是否存在)。 这将允许您的工作负载在进行这些更改时删除项目。
  3. 在开始此更改过程之前,更改您的客户端代码以编写状态 = N 的项目。更改过程可能会丢失这些新项目,但如果它们已经创建状态 = N 也没关系。
  4. 您不能使用BatchWriteItemsbatch_writer() )一起修改一组项目,因为此批处理操作只能替换项目 - 不能修改现有项目的属性。 在任何情况下, BatchWriteItems都不会降低成本(批次成本与它们包含的请求相同)。

阅读

  1. 要获取数据库中所有现有键的列表,进行上述读取,您需要使用Scan操作,将Projection设置为KEYS_ONLY以仅获取键(您不需要数据)。 不幸的是,您的成本将与阅读整个项目相同,而不仅仅是阅读钥匙。 所以所有这些 Scan 操作的成本总和将是读取整个数据库。

如果您为此表使用预置容量,您可以使用客户端请求未使用的任何多余容量在后台缓慢地进行此更改,基本上是“免费”的。

在您的情况下这是否有意义实际上取决于您配置了多少过剩容量(读取和写入)。如果您这样做。 您需要注意不要为此后台操作使用太多容量并伤害您的真实用户 - 您需要有某种 controller 通知容量超出错误并减少后台进程使用的容量量.

如果您实际上有很多已经支付的超额预置容量,您可以随心所欲地执行此后台操作,读取部分Scan可以尽可能快地并行完成(使用“并行扫描”功能),并且不同键的写入部分显然也可以并行完成。

以下代码使用batch_write_item DynamoDB API 以 25 的大小批量更新项目,这是batch_write_item在单个 API 调用中可以接收的最大项目数。 如果您的物品很大,您可能需要调整这个数字。

警告:这只是一个概念证明示例。 您应该自担风险使用。

import boto3

def update_status(item):
    item['status'] = {
        'S': 'N'
    }
    return item

client = boto3.client('dynamodb', region_name='<ddb-region>')
paginator = client.get_paginator('scan')
operation_parameters = {
  'TableName': '<ddb-table-name>',
  'PaginationConfig': {
    'PageSize': 25
  }
}
page_iterator = paginator.paginate(**operation_parameters)
for page in page_iterator:
    response = client.batch_write_item(RequestItems={
        '<ddb-table-name>': [
            {
                'PutRequest': {
                    'Item': update_status(item)
                }
            }
            for item in page['Items']
        ]
    })
    print(response)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM