【问题标题】:AWS Athena External Table not returning dataAWS Athena 外部表不返回数据
【发布时间】:2020-10-14 22:53:54
【问题描述】:

我使用下面的 DDL 脚本在 Athena 中创建了一个外部表。该表在 Athena 中成功创建,但是当我查询它时,它返回 0 行。指定的 s3 存储桶中的文件是 csv.gz 文件(我试图在 TBLPROPERTIES 中排除一个 json 文件)。 s3 存储桶与我查询它的帐户不同。假设我使用的 IAM 角色有权从另一个账户的源 S3 存储桶中读取数据。我还需要在 TBLPROPERTIES 中指定其他什么来完成这项工作吗?谢谢。

CREATE EXTERNAL TABLE default_schema.customer_all(
  identity_line_item_id string, 
  identity_time_interval string,
  payer string,
  YEAR string,
  MONTH string)
PARTITIONED BY ( 
  payer string, 
  year string, 
  month string)
ROW FORMAT SERDE 
  'org.apache.hadoop.hive.ql.io.parquet.serde.ParquetHiveSerDe' 
STORED AS INPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetInputFormat' 
OUTPUTFORMAT 
  'org.apache.hadoop.hive.ql.io.parquet.MapredParquetOutputFormat'
LOCATION
  's3://path/to/data/'
TBLPROPERTIES (
  'transient_lastDdlTime'='1602464902', 'classification'='csv', 'exclude'='s3://path/to/data/*.json', 'delimiter'=',','compressionType'='gzip');

【问题讨论】:

    标签: amazon-web-services amazon-s3 amazon-athena


    【解决方案1】:

    表是分区的,对于分区表,您必须手动添加所有分区,或配置partition projection,以便 Athena 知道在哪里可以找到每个分区的文件。

    可以使用 Athena DDL(即 SQL)或通过 Glue 数据目录 API 手动添加分区。我将向您展示如何使用 DDL 语句来实现,因为使用 API 非常冗长(虽然同步且速度更快,但更适合某些情况)。

    您可以像这样添加一个或多个分区:

    ALTER TABLE customer_all ADD IF NOT EXISTS
    PARTITION (player = 'foo', year = '2020', month = '10') LOCATION 's3://path/to/data/foo/2020/10/'
    PARTITION (player = 'bar', year = '2020', month = '10') LOCATION 's3://path/to/data/bar/2020/10/'
    PARTITION (player = 'bar', year = '2020', month = '11') LOCATION 's3://path/to/data/bar/2020/11/'
    

    首先给出分区键值,然后给出该分区的位置。请注意,分区位置不需要与分区键中的值相对应,如果您愿意,您的位置可以是 s3://path/to/data/2020-10/foo/(当然,为了您自己的理智,建议保持它们看起来相似)。

    使用分区投影通常比手动添加分区更方便,但它有一些限制。您的分区键必须是可枚举的或范围,而您的player 分区键很可能不是。不过,有一种特殊的分区投影键类型可以使用从查询中注入的值,并且如果您的所有查询都包含播放器分区键的值,则此配置可以工作:

    …
    TBLPROPERTIES (
      …
      'projection.enabled' = 'true',
      'storage.location.template' = 's3://path/to/data/${player}/${year}/${month}',
      'projection.player.type' = 'injected',
      'projection.year.type' = 'integer',
      'projection.year.range' = '2020-2030',
      'projection.month.type' = 'integer',
      'projection.month.range' = '1-12',
      'projection.month.digits' = '2'
    )
    

    我不能保证这会按原样工作,因为有些事情我不知道您的数据。比如我将年份设置为2020到2030之间,我不能说是否合理,如果你愿意,你可以将结束设置为9999,或者2022。我也不知道你的月份是不是零填充与否,我假设它们是,但如果不是,您需要删除 projection.month.digits 或将其更改为 1。我还假设您的数据像 storage.location.template 中的模式一样在 S3 上组织,这可能不是案例。

    并重复我上面所说的:此分区投影配置仅在所有查询都包含 player 的值时才有效,否则您将收到错误,因为 Athena 将无法确定在哪里可以找到数据 –它无法枚举player 的所有可能值。


    有些人会告诉你运行MSCK REPAIR TABLE customer_all 来加载你的分区,但这不是我推荐的。首先,它仅在您的数据使用 Hive 样式分区(例如…/player=foo/year=2020/month=3/…)进行分区时才有效,其次它非常缓慢且效率低下。如果您有几个分区,它可以正常工作,但如果您有数百个分区,它就不行,而且它不是管理分区的可扩展解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      • 2018-03-09
      • 2018-12-09
      • 1970-01-01
      相关资源
      最近更新 更多