【问题标题】:Copy parquet files then query them with Athena复制 parquet 文件,然后使用 Athena 查询它们
【发布时间】:2020-03-17 11:01:22
【问题描述】:

我使用 aws-data-wrangler (https://github.com/awslabs/aws-data-wrangler) 来处理 pandas 数据帧。处理完成后,我将它们导出到镶木地板文件:

wr.pandas.to_parquet(
    dataframe=my_dataframe,
    description=DESCRIPTION,
    columns_comments=COLUMN_COMMENTS,
    parameters=DATASET_TAGS,
    database=my_database,
    table=f"{table}_{latest_refresh_date}",
    path=f"s3://{bucket_out}/{sub_path}/{latest_refresh_date}/",
    procs_cpu_bound=1,
    partition_cols=["date"],
    mode="overwrite_partitions",
    preserve_index=False,
)

通过这种方式,它还创建了一个 Glue 表。 parquet 文件愉快地存在于 S3 存储桶中,我可以使用 Athena 使用 Glue 表的名称查询数据,如下所示:

select * from {table}_{latest_refresh_date}

现在假设我得到了新数据。新数据应存储在新的 S3 路径中:例如 s3://{bucket_out}/{sub_path}/{other_refresh_date}/。我像以前一样处理新数据,但我不想重新处理旧数据。因此,我使用简单的 S3 副本将 parquet 文件从旧路径复制到新路径。 wr.pandas.to_parquet 不处理旧数据。

现在想查询s3://{bucket_out}/{sub_path}/{other_refresh_date}/的数据,只能访问新的数据。

select * from {table}_{other_refresh_date}

看来我只能查询添加到 Glue 表中的数据。我天真地以为 Athena 会查询 S3 路径,但显然它比这更复杂。

您能否向我解释为什么会发生这种情况,并建议解决方法?我是否需要以某种方式将旧文件注册到新的 Athena 表中?

【问题讨论】:

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


    【解决方案1】:

    在不知道 Pandas 在幕后所做的细节的情况下,我怀疑问题在于它正在创建一个分区表(正如命令的 partition_cols=["date"] 部分所建议的那样)。分区表不仅有一个位置,每个分区也有一个位置。

    这可能是正在发生的事情:当您创建第一个表时,您最终会在 S3 上看到如下所示的数据:s3://example/table1/date=20200317/file.parquet,以及一个分区表,其分区的位置为 s3://example/table1/date=20200317/。表格也可能有位置,可能是s3://example/table1/,但这几乎没有任何意义——它没有用于任何用途,只是 Glue 要求表格有位置。

    当您创建下一个表时,您会在s3://example/table2/date=20200318/file.parquet 中获取数据,以及一个具有相应分区的表。我假设您接下来要做的是将第一个表中的数据复制到 s3://example/table2/date=20200317/file.parquettable1 -> table2 是不同的)。

    当您查询新表时,它不会在此位置查找,因为它不是属于其任何分区的位置。

    您可以通过多种方式解决此问题:

    • 也许您根本不需要分区,如果您删除命令的partition_cols=["date"] 部分会发生什么?你还有分区表吗? (检查 Glue 控制台,或在 Athena 中运行 SHOW CREATE TABLE tableX)。使用未分区的表,您可以将所需的任何数据移动到表的位置,Athena 会找到它。
    • 您可以将分区从第一个表添加到新表,而不是移动数据,而是在 Athena 中运行类似这样的操作:ALTER TABLE table2 ADD PARTITION ("date" = '20200317') LOCATION 's3://example/table1/date=20200317/'
    • 改为将分区添加到旧表中,或两者都添加。这并不重要,只取决于您在运行查询时要使用的名称。您还可以拥有一个手动设置的表作为主表,并将 Pandas 创建的表视为临时表。一旦 Pandas 创建了数据,您将其作为分区添加到主表并删除新创建的表。这样,您就可以为您的表取一个好听的名称,并且名称中不包含日期戳。
    • 如果您希望数据都在一个地方,您可以复制数据,然后像上面一样添加分区。
    • 可能有人会建议像上面那样复制数据,然后运行MSCK REPAIR TABLE。这行得通,但随着您获得更多分区,它会变得越来越慢,因此它不是一个可扩展的解决方案。

    【讨论】:

    • 你是对的。实际上,“问题”来自分区。使用分区,我需要修复表以注册数据。如果我放弃分区,那么 Athena 可以开箱即用地查询新数据。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多