我在EMR 5.19.0中运行Presto 0.212,因为AWS Athena不支持Presto支持的用户定义函数。我使用的EMR配置为使用粘合模式。我有预先存在的Parquet文件,这些文件在S3中已经以正确的分区格式存在。
最近的Presto版本似乎已经删除了创建和查看分区的功能。这就提出了一个问题:如何添加单个分区?我可以在AWS中使用Athena控制台并运行MSCK REPAIR mytable;
并正确创建分区,然后我可以使用Presto CLI或HUE成功查询。然而,我如何在Presto中做到这一点?
如果我在EMR主节点上的< code>presto-cli中尝试这样做:
use hive.default;
INSERT INTO "mytable$partitions" VALUES (2018, 9, 20)
我收到一个错误消息
java.sql.SQLException: Query failed (#20181113_172115_00004_yywie): com.facebook.presto.connector.system.SystemTableHandle cannot be cast to com.facebook.presto.hive.HiveTableHandle
(注意,我在Glue中使用数据库< code>default来存储模式。这就是“违约”的由来。)
Presto中的旧方法最近都被删除了(例如,alter table mytable add partition(p1=value,p2=value,p3=value)
或INSERT INTO table mytable partition(p1=值,p2=值,p3=值)
但是,在Presto CLI中,我可以查看存在的分区,在EMR主节点上输入此查询:
use hive.default;
select * from "mytable$partitions";
当然,最初查询结果是空的,因为不存在分区。如果我在Athena中手动运行MSCK修复来创建分区,那么该查询将显示所有已创建的分区。
如果我尝试在EMR主节点上使用HIVE CLI,它不起作用。
use default;
ALTER TABLE mytable
ADD PARTITION (p1=2018, p2=9, p3=20)
location 's3://bucketname/rootfolder/p1=2018/p2=9/p3=20/';
FAILED: SemanticException [Error 10001]: Table not found mytable
那么……如何使用Presto CLI,或使用HUE,甚至使用Hive CLI,将分区添加到存储在S3中的分区表中?既然普雷斯托已经失去了这样做的能力,那么应该怎么做呢?试图效仿前面的例子,比如这一个是行不通的。
虽然“MSCK REPAIR”可以工作,但这是一种昂贵的方法,并且会导致整个S3扫描。我更喜欢单独添加分区,而不是扫描整个S3存储桶来查找现有分区,特别是在向已经存在的大表添加一个新分区时。
我还注意到了第页上的这段引用,使用AWS Glue数据目录作为Hive的Metastore:
我们建议通过 Amazon EMR 使用应用程序创建表,而不是直接使用 AWS Glue 创建表。通过 AWS Glue 创建表可能会导致缺少必填字段并导致查询异常。
在电子病历中肯定有这样做的方法。这是什么?
事实证明,在EMR中,Hive和Presto需要单独的配置才能使用Glue目录。因此,我的AWS CLI脚本需要修改,以包含每一个能够做到这一点的配置。配置最终看起来是这样的:
--configurations '[
{
"Classification": "presto-connector-hive",
"Properties": { "hive.metastore.glue.datacatalog.enabled": "true" },
"Configurations":[]
},
{
"Classification": "hive-site",
"Properties": { "hive.metastore.client.factory.class": "com.amazonaws.glue.catalog.metastore.AWSGlueDataCatalogHiveClientFactory" }
}
]'
看起来当前的Presto版本不能直接创建或查看分区,但Hive可以。我的问题是Hive没有配置为查看Glue目录。一旦我解决了这个问题,Hive就能够使用如下语句创建分区
ALTER TABLE mytable ADD IF NOT EXISTS
PARTITION (p1=2018, p2=9, p3=18)
PARTITION (p1=2018, p2=9, p3=19)
PARTITION (p1=2018, p2=9, p3=20);