AWS EMR中SQL创建开源Delta Lake表后S3无文件插入报错的解决办法
问题描述
在AWS EMR环境使用开源Delta Lake时,Python中dataframe.write.format('delta').save()可正常执行,但通过SQL创建Delta表遇到异常:
执行以下CREATE TABLE语句后,Glue元数据存储中已生成表,但S3对应路径s3://<bucket_name>/test/foo无任何文件:
CREATE OR REPLACE TABLE test.foo (name string) USING delta LOCATION 's3://<bucket_name>/test/foo'
执行INSERT语句时抛出错误:org.apache.spark.sql.AnalysisException: Path does not exist
spark.sql('INSERT INTO test.foo (name) VALUES ("bar")');
解决方案
以下三种方法均可解决该问题:
1. 提前手动创建S3目标路径
Delta Lake的CREATE TABLE ... LOCATION语句不会自动初始化S3路径,需先确保路径存在。
- 用Spark API创建路径:
# 在执行CREATE TABLE前运行 spark.sparkContext._jvm.org.apache.hadoop.fs.FileSystem.get( spark.sparkContext._jsc.hadoopConfiguration() ).mkdirs( spark.sparkContext._jvm.org.apache.hadoop.fs.Path("s3://<bucket_name>/test/foo") )
- 或用AWS CLI创建:
aws s3 mb s3://<bucket_name>/test/foo
路径创建完成后,再执行原CREATE TABLE和INSERT语句即可正常运行。
2. 使用CTAS语句直接创建带数据的表
如果初始有测试数据,可通过CREATE TABLE AS SELECT语句一次性完成表注册与路径初始化,同时写入数据:
CREATE OR REPLACE TABLE test.foo USING delta LOCATION 's3://<bucket_name>/test/foo' AS SELECT 'bar' AS name
后续再执行INSERT语句就不会触发路径不存在的错误。
3. 启用Delta Lake自动路径初始化配置
添加Spark配置参数,允许空路径创建Delta表,执行CREATE TABLE时会自动生成Delta所需的元数据目录(_delta_log):
- 在EMR集群启动时,将该配置添加到Spark自定义参数中;
- 或在代码中动态设置:
spark.conf.set("spark.databricks.delta.createTable.allowEmptyLocation", "true")
设置完成后,再执行原CREATE TABLE语句,S3路径会自动初始化,之后即可正常插入数据。
内容的提问来源于stack exchange,提问作者dahuin
相关产品推荐
相关产品推荐

