Spark在S3创建空Delta表后执行Merge报错非Delta表问题咨询
触发原因
- Spark默认使用
CREATE TABLE IF NOT EXISTS ... USING DELTA LOCATION语法创建空表时,仅会在Hive元数据中记录表的schema、存储格式、路径等元信息,不会主动在指定的LOCATION路径下生成Delta表必需的_delta_log元数据目录。 - 只有当表有实际数据写入时,Spark才会生成
_delta_log目录,完成Delta表结构的初始化。空表状态下LOCATION路径下没有Delta元数据标识,执行Merge这类直接读取存储层Delta元数据的操作时,就会抛出路径不是Delta表的异常。
解决方案
可根据使用场景选择以下任意一种方案解决:
- 方案1:建表时添加参数强制初始化Delta结构
建表语句新增delta.createEmptyTable表属性,要求Spark建表时直接生成初始Delta日志,完整语句如下:
该参数从Delta 1.2.0版本开始支持,兼容所有Spark 3.x版本。CREATE TABLE IF NOT EXISTS t1 (pkey varchar(512), name varchar(100)) USING DELTA LOCATION 's3a://bucket/table_t1' TBLPROPERTIES ('delta.createEmptyTable' = 'true'); - 方案2:建表后执行空写入触发初始化
建表完成后写入空数据集触发_delta_log生成,不会产生实际业务数据,示例如下:-- SQL 方式 INSERT INTO t1 SELECT * FROM t1 WHERE 1=0;// Scala 方式 spark.emptyDataFrame.write.format("delta").mode("append").save("s3a://bucket/table_t1") - 方案3:Merge操作前补全初始化逻辑
若无法修改建表逻辑,可在执行Merge前先判断目标路径是否为合法Delta表,未初始化则先执行空写入操作,再运行Merge任务。
内容的提问来源于stack exchange,提问作者gaurav miglani
相关产品推荐
相关产品推荐

