Azure Synapse外部表报错:Parquet文件丢失无法访问
问题根源与修正步骤
核心问题1:外部表指向单个Parquet文件而非目录
你创建外部表时,LOCATION指定了具体的单个part文件路径,这是错误的:
LOCATION = 'transformed-data/filename=crime_data/part-00000-tid-3588581976832316109-20e2477d-82c0-47d9-ba75-cf341910855e-20-1.c000.snappy.parquet'
Databricks写入分区Parquet时,会生成临时文件最终重命名为正式part文件,后续即使仅执行一次overwrite操作,旧part文件也可能被清理或替换;此外ADLS或Synapse的后台机制也可能对孤立文件进行清理,导致单个文件消失。
正确做法是将LOCATION指向分区的父目录(即transformed-data),让Synapse自动扫描该目录下的所有分区文件。
核心问题2:数据源名称不匹配
你创建的外部数据源名称是[crime-data_crimedatasam_dfs_core_windows_net],但在外部表中引用的却是[crime-data_sam_dfs_core_windows_net],名称不一致。虽初始查询正常(可能是笔误),但这会导致后续访问的潜在问题。
修正后的外部表创建代码
-- 确保文件格式存在 IF NOT EXISTS (SELECT * FROM sys.external_file_formats WHERE name = 'SynapseParquetFormat') CREATE EXTERNAL FILE FORMAT [SynapseParquetFormat] WITH ( FORMAT_TYPE = PARQUET) GO -- 确保数据源存在(修正名称一致性) IF NOT EXISTS (SELECT * FROM sys.external_data_sources WHERE name = 'crime-data_crimedatasam_dfs_core_windows_net') CREATE EXTERNAL DATA SOURCE [crime-data_crimedatasam_dfs_core_windows_net] WITH ( LOCATION = 'abfss://crime-data@mycrimedata.dfs.core.windows.net' ) GO -- 创建指向分区目录的外部表,并包含分区列 CREATE EXTERNAL TABLE dbo.crime_data ( [ethnicity] nvarchar(80), [police_district] nvarchar(80), [lower_age] int, [upper_age] int, [filename] nvarchar(256) -- 添加分区列 ) WITH ( LOCATION = 'transformed-data', -- 指向分区根目录 DATA_SOURCE = [crime-data_crimedatasam_dfs_core_windows_net], -- 与创建的数据源名称一致 FILE_FORMAT = [SynapseParquetFormat], -- 启用分区发现,自动解析filename分区 PARTITION (filename nvarchar(256) AS REPLACE(SUBSTRING(filepath(), CHARINDEX('filename=', filepath()) + 9), '/', '')) ) GO -- 查询验证 SELECT TOP 100 * FROM dbo.crime_data GO
额外注意事项
- 确认Databricks写入逻辑:你当前的写入代码
cultural_split.write.partitionBy("filename").mode('overwrite').parquet("/mnt/crime/transformed-data")是正确的,默认会原子替换分区目录,避免文件被部分删除。 - 检查ADLS生命周期规则:若存在自动删除旧文件的规则,会导致文件消失。
- 确认权限持续性:确保Synapse工作区对ADLS路径拥有稳定的读写权限,权限变更也可能引发访问失败。
内容的提问来源于stack exchange,提问作者Samuel Appleton
相关产品推荐
相关产品推荐

