当前位置: 首页 > 知识库问答 >
问题:

我可以在单个Lambda函数中创建和填充dynamodb表吗?

明越
2023-03-14

我的代码基本上有两个部分,它们各自工作,但不能一起工作。所以我想我有一个语法问题。

第一部分是创建表,第二部分是填充表。问题是,这两个部分共享表名的变量。


   import os
   import boto3
   import botocore.session

   region = os.environ.get('AWS_DEFAULT_REGION', 'us-east-2')
   session = botocore.session.get_session()
   dynamo = session.create_client('dynamodb', region_name=region) 


   s3 = boto3.client('s3')
   dynamodb = boto3.resource('dynamodb')

   def lambda_handler(event, context):

    bucket = event['Records'][0]['s3']['bucket']['name']
    key = event['Records'][0]['s3']['object']['key']

    obj = s3.get_object(Bucket=bucket, Key=key)

    rows = obj['Body'].read().decode("utf-8"). split ('\n')

    table = dynamodb.Table(key)
    dynamodb.create_table(
    TableName=key,
    KeySchema=[
        {
            'AttributeName': 'first',
            'KeyType': 'HASH'  #Partition key
        },
        {
            'AttributeName': 'last',
            'KeyType': 'RANGE'  #Sort key
        }
    ],
    AttributeDefinitions=[
        {
            'AttributeName': 'first',
            'AttributeType': 'S'
        },
        {
            'AttributeName': 'last',
            'AttributeType': 'S'
        },

    ],
    ProvisionedThroughput={
        'ReadCapacityUnits': 5,
        'WriteCapacityUnits': 5
        }
    )
   # Wait for the table to exist before exiting
    print('Waiting for', key, '...')
    waiter = dynamo.get_waiter('table_exists')
    waiter.wait(TableName=key)
    with table.batch_writer() as batch:
        for row in rows:

            batch.put_item(Item={

                'first':row.split(',')[0],
                'last':row.split(',')[1],
                'age':row.split(',')[2],
                'date':row.split(',')[3]

            })

每当CSV被放入我的s3存储桶时,它就作为lambda函数运行。

运行后,它会成功创建表,但不会填充表。以“任务在3.00秒后超时”结尾。几秒钟后,它再次启动并返回“表已存在”,但仍然为空。

如果我只运行batch_writer部分,只要它已经存在,它就会填充表。

共有1个答案

翟英达
2023-03-14

简单的回答是,一个新表通常需要大约1秒的时间才能激活,而waterer.TableExists使用默认的轮询间隔20秒,这会导致lambda函数超时。

但到底发生了什么?

在内部,waterer.TableExists的功能大致与此伪代码类似。(为了简单起见,我省略了错误处理和其他细节。)

function waitForTable(tableName):
    while true:
        if (dynamodb.describeTable(tableName).status == active):
            return
        else:
            sleep 20 seconds

在你创建了你的桌子之后,你启动了服务员。当服务员调用descripbetable时,它看到该表尚未激活,因此等待20秒。lambda超时设置为3秒,因此在3秒后(服务员再次调用descripbetable之前),lambda函数终止。(这就是“任务超时”消息的含义。)

然后,当重试lambda函数时,表现在处于活动状态,因此当lambda函数到达dynamodb.create_table(...)调用时,DynamoDB将以错误响应,因为表已经存在。(因此,表已经存在错误消息。)

我怎么修理它?

你可以做几件事来解决这个问题,“最正确”的解决方案可能是把它们都做了。

  1. 您可以将服务员的延迟时间设置为较低的数字,例如1秒,如下所示:waiter.wait(TableName=key, WaiterConfig={'Delay': 1})
  2. 可以增加lambda函数的超时。创建表、读取S3文件并将其全部写入DynamoDB可能需要3秒钟以上的时间。如果需要重试请求,请选择一个数字,让lambda函数有时间恢复。如果您的函数适用于只有1-2行的文件,但对较大的文件失败,我建议尝试5秒钟,如果不能可靠地成功,增加到10秒钟。如果文件可能非常大,您应该考虑使用Lambda以外的东西。
  3. 假设您不关心覆盖现有表中的数据,那么您应该在尝试创建该表之前检查该表是否已经存在(或者尝试创建该表并忽略在以下情况下引发的ResourceAlreadyInUseExc0019已经存在)。请参阅如何检查DynamoDB表是否存在的其他SO答案,它解释了检查表是否存在的多种方法,包括每个表的代码示例
 类似资料:
  • 我需要创建PDF表格,可以用来从用户的输入。它们需要包含下拉框和文本框。请建议哪种软件或工具最适合我的目的

  • 我有一个Lambda函数,将多个DynamoDB流配置为事件源,这是更大管道的一部分。在进行检查时,我在一个下游组件中发现了一些缺失的数据。我想编写一个更简单的Lambda函数,将其配置为前面提到的DynamoDB流之一的事件源。这将导致我的一个DynamoDB流有两个Lambda函数从中读取。我想知道这样可以吗?这两个Lamdba函数是否都能保证接收流中的所有记录,是否有任何需要注意的资源(读/

  • 问题内容: 我那里有点问题。当我想在JSF中填充DataTable时,我必须先创建一个模型,然后在我的视图中使用它。就像这里的 Primefaces示例一样。 现在,我必须创建DataTable来显示来自Web服务的数据。我不知道会有多少列,我也不知道它们的名称…您能推荐一些明智的解决方案吗? PS。我也不知道如何从Web服务中返回数据-尚待确定。 编辑 问题答案: 收集中代表属性的数据。的表示列

  • 问题内容: 我可以从数组中读取每种语法的数据: 但是有可能同样填充数组。说,有价值观? 我没有发明这样的方法,而是想问你我是否错。 问题答案: 在Java Docs中 , for-each循环隐藏了迭代器,因此您无法调用remove。因此,for-each 覆盖绝大多数案例。 因此,简单来说,不可能填充数组。

  • 问题内容: 在Java中,我们可以在一个类中创建多少个构造函数。 问题答案: 严格来说,JVM类文件格式将一个类的方法(包括所有构造函数)限制为少于65536。而且,根据汤姆·哈顿(Tom Hawtin)的说法,有效限制为65527。每个方法签名在常量池中占用一个插槽。由于65535池条目中的某些条目(不可避免地)被其他事物消耗,因此格式良好的类文件不可能使用所有可能的方法/构造函数ID。 参考-

  • 在Java中,我们可以在一个类中创建多少构造函数。