【问题标题】:How to overwrite table using INSERT INTO based on partition? - Athena如何使用基于分区的 INSERT INTO 覆盖表? - 雅典娜
【发布时间】:2021-10-18 18:45:45
【问题描述】:

我目前正在使用INSERT INTO Athena 命令通过自动作业更新我由execution_date 分区的表。

我现在想通过每天两次更新表来配置此作业,但仍按execution_date 进行分区。所以我早上的工作应该像往常一样工作,但是我下午用相同的execution_date 运行的工作应该会覆盖从早上开始也被相同的execution_date 分区的记录。

我已经研究了MSCK REPAIR TABLE,但我不确定它如何适用于我的用例。

如何使用 Athena 的 INSERT INTO 命令覆盖按相同值分区的记录?

【问题讨论】:

    标签: sql amazon-web-services sql-insert amazon-athena database-partitioning


    【解决方案1】:

    Athena 永远不会覆盖数据。如果你想删除或替换数据,你必须自己做。如果输出位置有任何东西,INSERT INTOCREATE TABLE AS (CTAS) 将拒绝运行。

    您可以做什么取决于您的要求。最简单的方法是在运行 INSERT INTO 命令之前删除数据。这样做的缺点是在命令运行之前分区中没有数据。 IE。在同一时间窗口中运行的查询将看不到当天的任何数据。您可以确保在重新处理期间不运行任何查询并避免不一致,但如果这不是一个选项,它会变得更加复杂。

    我过去采用的另一种方法是使用 CTAS 作为转换机制,然后将转换后的数据移动到位。使用新的UNLOAD 功能,这变得更容易一些,因为没有创建表。您可以做的是运行 UNLOAD 命令而不是您的 INSERT INTO 并使用临时输出位置。如果这是一天中的第一次运行,您只需将文件复制到正确的位置并 create a partition using the Glue Data Catalog API - 或者更好地使用 partition projection 以避免完全处理分区。如果这是当天的第二次运行,则删除现有分区中的文件并将新文件复制到它们的位置。然后删除UNLOAD 命令的输出位置中的所有内容。

    当分区中没有数据时,以及分区中有部分数据时,此替代方案的时间窗口仍然很短。查询可以在您开始删除旧文件和将所有新文件复制到分区位置之前的任何时间点运行。窗口最多不应超过几秒钟,特别是如果您并行执行所有删除操作,然后并行执行所有复制操作,但它永远不会为零。

    如果您真的想避免不一致,还有另一种选择,它使用分区位置不必与分区键值相对应的事实。您可以像以前一样运行相同的UNLOAD 命令,但设置输出位置,以便输出与其他分区在同一位置结束,但具有唯一的后缀。如果您的表按日期分区,并且您的分区具有像 s3://example-bucket/data/2021-08-16/s3://example-bucket/data/2021-08-17/ 这样的 URI,则您将 UNLOAD 命令的输出位置设置为像 s3://example-bucket/data/2021-08-17_asdf1234/ 这样的 URI,其中“asdf1234”是每个跑步。转换完成后,您 update the partition's location using the Glue Data Catalog API 指向新位置,但使用相同的分区键值,例如“2021 年 8 月 17 日”。更新分区的位置后,您将删除旧位置的文件。这将确保运行的任何查询都将看到旧数据或新数据,但绝不会看不到数据或部分数据。

    没有办法让 Athena 自动替换分区。哪种替代方案适合您,这取决于查询在更新期间看不到数据或看到部分数据的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-07
      • 2020-03-25
      • 2022-01-03
      • 2018-10-19
      相关资源
      最近更新 更多