为什么Pandas库无法从Azure Synapse Spark池读取Blob存储中更新的Excel文件?

1 投票
1 回答
52 浏览
提问于 2025-04-14 18:19

主题:在Synapse Spark池中使用pd.ExcelFile()读取Blob存储中的更新Excel文件时出现问题。

我在使用Python 3.11的Azure Synapse Spark池(版本3.3)时遇到了一个问题,无法读取更新后的Excel文件。我的设置如下:

数据来源:存储在Azure Blob存储中的Excel文件。
更新过程:这个文件定期从SharePoint更新新数据,使用的是Microsoft Power Automate。
读取数据:我在Synapse笔记本中使用pandas.ExcelFile()来读取这个Excel文件。

问题:

  • 当笔记本第一次运行时,它可以成功读取数据,通过传递abfss路径到一个Excel(xls或xlsx)文件,使用初始的ExcelFile(),并填充数据框。

xlsx = pd.ExcelFile(file_path)

wb = pd.read_excel(xlsx,sheet_name='discount')

  • 但是,如果笔记本已经在运行,而Excel文件在SharePoint中被更新(触发Power Automate流程以更新Blob存储),我会遇到一个错误:HttpResponseError: 指定的范围对于当前资源的大小无效。
RequestId:8a416b5b-401e-0070-6581-6e06f0000000
Time:2024-03-04T22:16:21.5453793Z
ErrorCode:InvalidRange
Content: <?xml version="1.0" encoding="utf-8"?><Error><Code>InvalidRange</Code><Message>The range specified is invalid for the current size of the resource.

如果我停止Spark池并重新启动笔记本内核,更新后的Excel文件就会再次被正确读取。

问题:

  1. 为什么在笔记本运行时,pd.ExcelFile()无法读取更新后的Excel文件,导致HttpResponseError。
  2. 有没有办法在不重新启动内核的情况下读取更新的文件,可能利用Excel文件的机制?

我已经搜索了关于这个问题的解决方案,但唯一能让它工作的办法是强制刷新并再次运行pd.ExcelFile()的脚本。但这并不可持续,我需要在数据框更新时让它正常工作。任何见解或建议都将非常感谢。

1 个回答

0

当我尝试下面的代码时:

import pandas as pd
import adlfs
spark.conf.set("fs.azure.account.key.stgsynp.dfs.core.windows.net", "TzXfEEHLnOojJcE1lqfV4HV9rK0BDpZaHq/Yqo6eH3ZKclogX5zDGwby2EMov8xmdZezCDdGWlv5+AStNeictA==")
file_path = "abfss://folder02@stgsynp.dfs.core.windows.net/sheet1.xlsx"
def read_excel_file(file_path, sheet_name='Sheet1'):
    fs = adlfs.AzureBlobFileSystem(account_name='stgsynp', account_key='TzXfEEHLnOojJcE1lqfV4HV9rK0BDpZaHq/Yqo6eH3ZKclogX5zDGwby2EMov8xmdZezCDdGWlv5+AStNeictA==')
    with fs.open(file_path, 'rb') as f:
        df = pd.read_excel(f, sheet_name=sheet_name)
    return df
df = read_excel_file(file_path)
print("Initial data:")
print(df)

我遇到了这个错误:

HttpResponseError: The specifed resource name contains invalid characters.

我尝试了下面的方法:

import pandas as pd
def read_excel_file(file_path, sheet_name='Sheet1'):
    df = pd.read_excel(file_path, sheet_name=sheet_name)
    return df
file_path = 'https://stgsynp.dfs.core.windows.net/folder02/sheet1.xlsx?sv=2022-11-02&ss=bfqt&srt=sco&sp=rwdlacupyx&se=2024-03-05T17:52:01Z&st=2024-03-05T09:52:01Z&spr=https&sig=uMKiqL4JXL%2FT0sZcjargX1GjDEL7eaWtzRIPyVxYn6U%3D'
df = read_excel_file(file_path)
print("Initial data:")
print(df)

结果:

updated data:
      Name  Age         City
0   Thomas   26  small heath
1     jhon   22  small heath
2      Ada   16  small heath
3  aurthur   30  small heath
4   fredie   30  small heath
5      sai   99   shamshabad

在上面的代码中,定义了一个函数 (read_excel_file),它需要两个参数:file_path(Excel文件的路径)和sheet_name(要读取的工作表名称,默认是'Sheet1')。

这个函数使用pandas库中的 read_excel 函数来读取指定的Excel文件和工作表,并把它们放到一个叫 (df) 的数据框中。

不过,pandas.read_excel 方法不支持使用 wasbsabfss 这种格式的链接来访问Excel文件。

在这种情况下,你需要使用SAS令牌:

要通过Azure门户创建一个SAS令牌,以便访问Azure存储账户:

首先,登录到Azure门户,选择你的Azure存储账户。
然后,进入存储账户的设置部分。
点击“共享访问签名”来生成一个SAS令牌。

ReadExcel=pd.read_excel('https://<account name>.dfs.core.windows.net/<file system>/<path>?<sas token>')  
print(ReadExcel)  

参考: Azure Synapse Workspace - 如何使用Pandas或PySpark从Data Lake Gen2读取Excel文件?

撰写回答