代码之家  ›  专栏  ›  技术社区  ›  Prasanna Nandakumar

自动更新Athena分区-msck修复

  •  0
  • Prasanna Nandakumar  · 技术社区  · 6 年前

    我有一个库存桶-在桶里-我有6个文件夹。

    在雅典娜每6个文件夹-我在雅典娜有6张桌子。 现在我必须更新分区-当一个文件被放入6个文件夹中的任何一个时。 如何在一个lambda for s3事件触发器中编写多个sql(6sql)。

    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 回复  |  直到 6 年前
        1
  •  0
  •   Theo    6 年前

    首先,我检查被删除文件的键,只更新指向文件被删除的前缀的表。例如,如果您的文件夹和表 prefix0 , prefix1 , prefix2 ,等等,而丢弃的文件具有密钥 prefix1/some-file 您只使用位置更新表 前缀1 . 不需要更新其他表,它们的数据没有更改。

    但是,我建议不要使用 MSCK REPAIR TABLE 为此。这个命令几乎在所有可能的方面都很糟糕。当您向表的前缀添加更多对象时,它的效率非常低,性能也越来越差。它看起来不像你在lambda中等待它完成,所以至少你没有为它的低效率付出代价,但是有更好的方法来添加分区。

    您可以直接使用glue api(在hoods下面,athena表是glue目录中的表),但这实际上有点复杂,因为您需要指定大量元数据(glue api的一个缺点)。

    我建议你不要 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 pk1 SQL如下所示:

    ALTER TABLE some_database.some_table
    ADD IF NOT EXISTS
    PARTITION (pk0 = 'foo', pk1 = 'bar') LOCATION 's3://some-bucket/pk0=foo/pk1=bar/'