我有一个库存桶-在桶内-我有6个文件夹。
在雅典娜中,每个6个文件夹-我在雅典娜中有6张桌子。 现在,我必须更新分区-当文件拖放到6个文件夹中的任何一个中时。 如何在一个Lambda中为s3事件触发器编写多个sql(6 Sql)。
import boto3
def lambda_handler(event, context):
bucket_name = 'some_bucket'
client = boto3.client('athena')
config = {
'OutputLocation': 's3://' + bucket_name + '/',
'EncryptionConfiguration': {'EncryptionOption': 'SSE_S3'}
}
# Query Execution Parameters
sql = 'MSCK REPAIR TABLE some_database.some_table'
context = {'Database': 'some_database'}
client.start_query_execution(QueryString = sql,
QueryExecutionContext = context,
ResultConfiguration = config)
数据库是相同的;但是我有6个不同的表。我必须更新所有6张桌子。
答案 0 :(得分:0)
首先,我将检查已删除文件的密钥,仅更新指向该文件已删除前缀的表。例如。如果您的文件夹和表是prefix0
,prefix1
,prefix2
等,并且所删除的文件具有密钥prefix1/some-file
,则您仅更新位置为{{1}的表}。无需更新其他表,它们的数据没有更改。
但是,我建议不要使用prefix1
。该命令几乎在所有可能的方式中都非常糟糕。当在表的前缀中添加更多对象时,它的效率非常低下,并且性能变得越来越差。它看起来并不像您在等待它在Lambda中完成一样,所以至少您不必为它的低效付出代价,但是添加分区的方法要好得多。
您可以直接使用Glue API(Athena表在幕后是Glue目录中的表),但是由于需要指定很多元数据(Glue API的缺点),显示起来实际上有点复杂。
我建议您不要MSCK REPAIR TABLE
,而要MSCK REPAIR TABLE …
:
更改行
ALTER TABLE ADD PARTITION …
到
sql = 'MSCK REPAIR TABLE some_database.some_table'
提示sql = 'ALTER TABLE some_database.some_table ADD IF NOT EXISTS PARTITION (…) LOCATION \'s3://…\''
的部分,您必须从对象的键中提取出来。如果您的键看起来像…
,并且您的表具有分区键s3://some-bucket/pk0=foo/pk1=bar/object.gz
和pk0
,则SQL将如下所示:
pk1