amazon-web-services - 通过 AWS 上的 API 在胶水表上添加分区?

标签 amazon-web-services amazon-s3 amazon-athena aws-glue

我有一个不断被新数据填充的 S3 存储桶,我正在使用 Athena 和 Glue 来查询该数据,问题是如果胶水不知道创建了一个新分区,它就不会搜索它需要搜索的内容那里。如果我每次需要一个新分区时都调用 API 来运行 Glue 爬虫,代价太高了,所以最好的解决方案是告诉胶水添加了一个新分区,即在它的属性表中创建一个新分区。我查看了 AWS 文档,但没有运气,我正在将 Java 与 AWS 一起使用。有什么帮助吗?

最佳答案

您可能想使用 batch_create_partition()粘合 api 以注册新分区。它不需要任何昂贵的操作,如 MSCK REPAIR TABLE 或重新爬行。

我有一个类似的用例,我为此编写了一个 python 脚本,它执行以下操作 -

步骤 1 - 获取表信息并从中解析注册分区所需的必要信息。

# Fetching table information from glue catalog
logger.info("Fetching table info for {}.{}".format(l_database, l_table))
try:
    response = l_client.get_table(
        CatalogId=l_catalog_id,
        DatabaseName=l_database,
        Name=l_table
    )
except Exception as error:
    logger.error("Exception while fetching table info for {}.{} - {}"
                 .format(l_database, l_table, error))
    sys.exit(-1)

# Parsing table info required to create partitions from table
input_format = response['Table']['StorageDescriptor']['InputFormat']
output_format = response['Table']['StorageDescriptor']['OutputFormat']
table_location = response['Table']['StorageDescriptor']['Location']
serde_info = response['Table']['StorageDescriptor']['SerdeInfo']
partition_keys = response['Table']['PartitionKeys']

第 2 步 - 生成列表字典,其中每个列表都包含用于创建单个分区的信息。所有列表将具有相同的结构,但它们的分区特定值将更改(年、月、日、小时)

def generate_partition_input_list(start_date, num_of_days, table_location,
                                  input_format, output_format, serde_info):
    input_list = []  # Initializing empty list
    today = datetime.utcnow().date()
    if start_date > today:  # To handle scenarios if any future partitions are created manually
        start_date = today
    end_date = today + timedelta(days=num_of_days)  # Getting end date till which partitions needs to be created
    logger.info("Partitions to be created from {} to {}".format(start_date, end_date))

    for input_date in date_range(start_date, end_date):
        # Formatting partition values by padding required zeroes and converting into string
        year = str(input_date)[0:4].zfill(4)
        month = str(input_date)[5:7].zfill(2)
        day = str(input_date)[8:10].zfill(2)
        for hour in range(24):  # Looping over 24 hours to generate partition input for 24 hours for a day
            hour = str('{:02d}'.format(hour))  # Padding zero to make sure that hour is in two digits
            part_location = "{}{}/{}/{}/{}/".format(table_location, year, month, day, hour)
            input_dict = {
                'Values': [
                    year, month, day, hour
                ],
                'StorageDescriptor': {
                    'Location': part_location,
                    'InputFormat': input_format,
                    'OutputFormat': output_format,
                    'SerdeInfo': serde_info
                }
            }
            input_list.append(input_dict.copy())
    return input_list

第 3 步 - 调用 batch_create_partition() API

for each_input in break_list_into_chunks(partition_input_list, 100):
    create_partition_response = client.batch_create_partition(
        CatalogId=catalog_id,
        DatabaseName=l_database,
        TableName=l_table,
        PartitionInputList=each_input
    )

单个 api 调用中有 100 个分区的限制,因此,如果您要创建 100 个以上的分区,那么您需要将列表分成多个块并对其进行迭代。

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/glue.html#Glue.Client.batch_create_partition

关于amazon-web-services - 通过 AWS 上的 API 在胶水表上添加分区?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50638868/

相关文章:

sql - AWS Athena 使用 AND 条件查询 JSON 数组

amazon-web-services - 是否可以使用 AWS Athena 查询压缩文件?

sql - AWS Athena 文件系统上缺少表

amazon-web-services - 带有代理 Lambda : Invalid permissions on Lambda function 的 AWS API 网关

mysql - Amazon RDS 和管理我自己的数据库

amazon-web-services - 在 SQS lambda 环境中扇出的推荐方法是什么?

amazon-web-services - 如果 lambda 代码上传到 S3,如何更新 lambda 函数代码

amazon-web-services - 显示表,描述 redshift 中等效的表

amazon-web-services - 通过 HTTPS 提供静态 S3 网站时降低 CloudFront 成本

bash - 寻找 AWK 替代方案来加速此命令