Azure Synapse外部表无法被PowerBI/SSMS访问问题求助
我在Azure存储账户的目录里有个Delta表,用下面的SQL在Azure Synapse里创建了外部表:
IF NOT EXISTS (SELECT * FROM sys.external_file_formats WHERE name = 'SynapseDeltaFormat') CREATE EXTERNAL FILE FORMAT [SynapseDeltaFormat] WITH ( FORMAT_TYPE = DELTA) GO IF NOT EXISTS (SELECT * FROM sys.external_data_sources WHERE name = 'cla_cladata_dfs_core_windows_net') CREATE EXTERNAL DATA SOURCE [cla_cladata_dfs_core_windows_net] WITH ( LOCATION = 'abfss://cla@cladata.dfs.core.windows.net' ) GO CREATE EXTERNAL TABLE cla.ExportDataScores ( [GlobalID] int, [Name] nvarchar(400), [Metric] nvarchar(400), [Score] real ) WITH ( LOCATION = 'ExportDataScores/', DATA_SOURCE = [cla_cladata_dfs_core_windows_net], FILE_FORMAT = [SynapseDeltaFormat] ) GO SELECT TOP 100 * FROM cla.ExportDataScores GO
在Synapse内部查这个外部表完全没问题,但用PowerBI通过SQL Server连接字符串+用户名密码导入数据时,能看到表,但预览就报错:
DataSource.Error: Microsoft SQL: Content of directory on path 'https://cladata.dfs.core.windows.net/cla/ExportDataScores/_delta_log/*.*' cannot be listed. Detalles: DataSourceKind=SQL DataSourcePath=my-db.sql.azuresynapse.net;My DB Message=Content of directory on path 'https://cla.dfs.core.windows.net/cla/ExportDataScores/_delta_log/*.*' cannot be listed. ErrorCode=-2146232060
另外,在Azure VM上用SSMS连数据库后查这个表,也报一样的错:
Msg 13807, Level 16, State 1, Line 1 Content of directory on path 'https://cladata.dfs.core.windows.net/cla/ExportDataScores/_delta_log/*.*' cannot be listed.
已经确认过:
- 连PowerBI的用户在Synapse里执行查询正常,权限没问题
- 存储账户和Synapse都开了公网访问
1. 补全外部数据源的身份验证配置
你创建外部数据源的时候没指定身份验证方式,Synapse内部查询用的是工作区托管身份,但PowerBI、SSMS这类外部工具连接时,会用执行查询的用户身份去访问存储账户,必须给外部数据源加上身份验证配置:
方案A:用Azure AD passthrough(推荐)
修改外部数据源的创建语句,加上CREDENTIAL = [WorkspaceIdentity],让外部工具的用户身份通过Azure AD传递到存储账户:
IF NOT EXISTS (SELECT * FROM sys.external_data_sources WHERE name = 'cla_cladata_dfs_core_windows_net') CREATE EXTERNAL DATA SOURCE [cla_cladata_dfs_core_windows_net] WITH ( LOCATION = 'abfss://cla@cladata.dfs.core.windows.net', CREDENTIAL = [WorkspaceIdentity] ) GO
之后要确保这个用户在存储账户的cla容器上有Storage Blob Data Reader权限,去Azure门户的存储账户->访问控制(IAM)里加角色分配就行。
方案B:用存储账户密钥或SAS令牌
如果没法用Azure AD身份验证,就创建数据库范围凭据,再关联到外部数据源:
-- 创建数据库范围凭据 CREATE DATABASE SCOPED CREDENTIAL StorageAccountCredential WITH IDENTITY = 'SHARED ACCESS SIGNATURE', SECRET = '你的SAS令牌(注意不要开头的?)'; -- 修改外部数据源 ALTER EXTERNAL DATA SOURCE [cla_cladata_dfs_core_windows_net] WITH ( LOCATION = 'abfss://cla@cladata.dfs.core.windows.net', CREDENTIAL = StorageAccountCredential );
注意SAS令牌得有对cla容器的List和Read权限。
2. 检查存储账户的网络规则
就算开了公网访问,存储账户可能设了防火墙规则,得确保:
- PowerBI所在的IP或网络被允许访问存储账户(去存储账户->网络->防火墙和虚拟网络里加允许的IP范围)
- Azure VM的IP地址加到存储账户的防火墙允许列表里
- 如果用了VNet集成,得确认Synapse和VM、PowerBI的网络能连通
3. 验证Delta表的目录结构
去存储账户里看看cla/ExportDataScores/路径下的_delta_log目录是不是存在,里面有没有有效的日志文件,有没有损坏或者权限问题。用Azure存储浏览器就能查看这个目录的内容,确认能不能正常访问。
4. 确认Synapse SQL池的权限设置
确保执行查询的用户对外部表cla.ExportDataScores有SELECT权限,同时对外部数据源和外部文件格式有REFERENCES权限:
GRANT SELECT ON OBJECT::cla.ExportDataScores TO [你的用户名]; GRANT REFERENCES ON EXTERNAL DATA SOURCE::cla_cladata_dfs_core_windows_net TO [你的用户名]; GRANT REFERENCES ON EXTERNAL FILE FORMAT::SynapseDeltaFormat TO [你的用户名];
内容的提问来源于stack exchange,提问作者Asfandyar Abbasi

