首页 > 解决方案 > 使用 AWS Athena 在 AWS Glue 中复制表

问题描述

我在 AWS Glue 中有一个表,它使用 S3 存储桶作为数据位置。我想对该现有表执行 Athena 查询,并使用查询结果创建一个新的 Glue 表。

我尝试创建一个新的 Glue 表,将其指向 S3 中的新位置,并将 Athena 查询结果通过管道传输到该 S3 位置。这几乎完成了我想要的,但是

  1. 一个 .csv.metadata 文件与实际的 .csv 输出(由 Glue 表在读取指定 s3 位置中的所有文件时读取)一起放置在此位置。
  2. csv 文件在每个字段周围放置双引号,这会破坏 Glue 表中定义的使用数字的任何 fieldSchema

这些服务都是为了协同工作而设计的,因此必须有适当的方法来实现这一点。任何建议将不胜感激:)

标签: amazon-web-servicesamazon-s3aws-sdkamazon-athenaaws-glue

解决方案


这样做的方法是使用CTAS 查询语句

(CTAS) 查询根据CREATE TABLE AS SELECT来自另一个查询的 SELECT 语句的结果在 Athena 中创建一个新表。Athena 将 CTAS 语句创建的数据文件存储在 Amazon S3 中的指定位置。

例如:

CREATE TABLE new_table
WITH (
     external_location = 's3://my_athena_results/new_table_files/'
) AS (
    -- Here goes your normal query 
    SELECT 
        *
    FROM 
        old_table;
)

虽然有一些限制。但是,对于您的情况,最重要的是:

  1. 在 Amazon S3 中存储 CTAS 查询结果的目标位置必须为空。
  2. 这同样适用于新表的名称,即它不应该存在于 AWS Glue 数据目录中。
  3. 通常,您无法明确控制 CTAS 查询将创建多少文件,因为 Athena 是一个分布式系统。但是,可以尝试使用“此解决方法” ,它在子句 中使用bucketed_bybucket_count字段WITH
    CREATE TABLE new_table
    WITH (
        external_location = 's3://my_athena_results/new_table_files/',
        bucketed_by=ARRAY['some_column_from_select'],
        bucket_count=1
    ) AS (
        -- Here goes your normal query 
        SELECT 
            *
        FROM 
            old_table;
    )
    

除了创建新文件和定义与您关联的表外,还可以将数据转换为不同的文件格式,例如 Parquet、JSON 等。


推荐阅读