Databricks Unity Catalog外部表支持哪些写入操作?
Databricks Unity Catalog外部表写入操作支持与问题解决
一、支持的写入操作
Unity Catalog外部表支持追加(Append)、覆盖(Overwrite)、**更新插入(Merge)**操作,但有两个前提:
- 表的存储路径必须指向目录而非单个文件
- 数据格式需对应支持写入模式(比如CSV支持追加/覆盖,Parquet支持全部三种模式)
二、单个文件路径导致的INSERT INTO错误
你创建表时指定的LOCATION是单个CSV文件(/path/to/data.csv),而Databricks外部表要求存储路径必须是目录——执行INSERT INTO时,系统需要向目录下写入新的数据文件,而非修改已存在的单个文件,因此触发报错。
修复方法:
- 将原CSV文件移动到一个独立目录下,例如
abfss://<container>@<adls-account>/path/to/csv_dir/ - 重新创建外部表,指向该目录:
CREATE TABLE ext_tbl USING CSV OPTIONS ( header "true", inferSchema "true" ) LOCATION 'abfss://<container>@<adls-account>/path/to/csv_dir/'
- 之后即可执行标准写入操作:
-- 追加数据 INSERT INTO ext_tbl VALUES (val1, val2, ...); -- 覆盖全表数据 INSERT OVERWRITE ext_tbl VALUES (val1, val2, ...);
三、saveAsTable权限错误解决
报错"This request is not authorized..."通常由两类权限问题导致:
- 当前执行身份(用户/服务主体)没有目标ADLS目录的写入权限(需分配Storage Blob Data Contributor角色到对应容器/目录)
- 没有Unity Catalog中目标数据库/表的CREATE/ALTER权限
修复步骤:
- 确认ADLS权限:在Azure门户给Databricks使用的身份分配对应存储资源的写入权限
- 确认Unity Catalog权限:确保用户拥有目标数据库的
USE SCHEMA和CREATE TABLE权限,或对已存在表的ALTER权限 - 规范DataFrame写入方式:
# 追加写入已存在的外部表 new_df.write.mode("append").insertInto("ext_tbl") # 创建外部表并写入数据(表不存在时) new_df.write.format("csv") .option("header", "true") .mode("overwrite") .option("path", "abfss://<container>@<adls-account>/path/to/csv_dir/") .saveAsTable("ext_iris_csv")
四、Parquet分区外部表的写入
Parquet格式支持所有三种写入操作,分区表的写入效率更高,适合大规模数据场景:
创建分区外部表示例:
CREATE TABLE ext_parquet_tbl ( id INT, name STRING, value DOUBLE ) PARTITIONED BY (dt DATE) USING PARQUET LOCATION 'abfss://<container>@<adls-account>/path/to/parquet_partitioned/'
常见写入操作:
- 追加分区数据:
INSERT INTO ext_parquet_tbl PARTITION (dt='2024-05-20') VALUES (1, 'test', 3.14);
- 覆盖指定分区:
INSERT OVERWRITE ext_parquet_tbl PARTITION (dt='2024-05-20') VALUES (2, 'updated', 2.71);
- 更新插入(Merge):
MERGE INTO ext_parquet_tbl t USING (SELECT id, name, value, dt FROM update_df) s ON t.id = s.id AND t.dt = s.dt WHEN MATCHED THEN UPDATE SET t.value = s.value WHEN NOT MATCHED THEN INSERT (id, name, value, dt) VALUES (s.id, s.name, s.value, s.dt);
DataFrame写入分区表:
# 追加写入分区表 update_df.write.mode("append") .partitionBy("dt") .insertInto("ext_parquet_tbl") # 动态覆盖指定分区(仅覆盖匹配的分区,不影响其他分区) update_df.write.mode("overwrite") .option("partitionOverwriteMode", "dynamic") .partitionBy("dt") .insertInto("ext_parquet_tbl")
内容的提问来源于stack exchange,提问作者Minura Punchihewa
相关产品推荐
相关产品推荐

