为什么Pandas库无法从Azure Synapse Spark池读取Blob存储中更新的Excel文件?
主题:在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文件就会再次被正确读取。
问题:
- 为什么在笔记本运行时,pd.ExcelFile()无法读取更新后的Excel文件,导致HttpResponseError。
- 有没有办法在不重新启动内核的情况下读取更新的文件,可能利用Excel文件的机制?
我已经搜索了关于这个问题的解决方案,但唯一能让它工作的办法是强制刷新并再次运行pd.ExcelFile()的脚本。但这并不可持续,我需要在数据框更新时让它正常工作。任何见解或建议都将非常感谢。
1 个回答
当我尝试下面的代码时:
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
方法不支持使用 wasbs 或 abfss 这种格式的链接来访问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文件?