Azure Blob存储中Python脚本添加CSV到Excel报错求助
问题:Azure Blob存储中Excel文件添加工作表失败,出现域名解析错误
我有一个存储在Azure Blob中的Excel文件,包含4个工作表(tab2、tab3、tab4、tab6),需要把两个CSV文件分别作为第一个工作表(tab1)和倒数第二个工作表(tab5)添加进去,编写的Python脚本如下:
from azure.storage.blob import BlobServiceClient import pandas as pd from io import BytesIO from datetime import date today = date.today().strftime("%Y%m%d") connection_string = "DefaultEndpointsProtocol=https;AccountName=MyAccount;AccountKey=accountkey;EndpointSuffix=myendpoint.blob.core.windows.net/myproj" container_name = "MyContainer/Prj1" excel_blob_name = "My Excel.xlsx" csv_blob_1_name = "My_csv1_"+today+".csv" csv_blob_2_name = "My_csv2_"+today+".csv" # Initialize Blob Service Client blob_service_client = BlobServiceClient.from_connection_string(connection_string) # Read Excel file from Blob Storage excel_blob_client = blob_service_client.get_blob_client(container=container_name, blob=excel_blob_name) excel_blob_data = BytesIO(excel_blob_client.download_blob().readall()) # Read CSV files from Blob Storage csv_blob_client_1 = blob_service_client.get_blob_client(container=container_name, blob=csv_blob_1_name) csv_blob_data_1 = BytesIO(csv_blob_client_1.download_blob().readall()) df_csv_1 = pd.read_csv(csv_blob_data_1) csv_blob_client_2 = blob_service_client.get_blob_client(container=container_name, blob=csv_blob_2_name) csv_blob_data_2 = BytesIO(csv_blob_client_2.download_blob().readall()) df_csv_2 = pd.read_csv(csv_blob_data_2) # Load the Excel file in memory with pd.ExcelWriter(excel_blob_data, mode="a", engine="openpyxl") as excel_writer: df_csv_1.to_excel(excel_writer, sheet_name="tab1", index=False) df_csv_2.to_excel(excel_writer, sheet_name="tab5", index=False) # Save modified Excel file back to Blob Storage excel_blob_data.seek(0) # Reset stream position excel_blob_client.upload_blob(excel_blob_data, overwrite=True)
运行脚本时出现以下域名解析错误:
Traceback (most recent call last): File "d:\batch\tasks\workitems\adfv2-ProjCont\job-1\3e150412-3328-4b72-b09b-29494f29396b\wd\csv_join_excel.py", line 23, in <module> excel_blob_data = BytesIO(excel_blob_client.download_blob().readall()) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\tracing\decorator.py", line 119, in wrapper_use_tracer return func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\storage\blob\_blob_client.py", line 753, in download_blob return StorageStreamDownloader(**options) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\storage\blob\_download.py", line 403, in __init__ self._response = self._initial_request() ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\storage\blob\_download.py", line 456, in _initial_request location_mode, response = cast(Tuple[Optional[str], Any], self._clients.blob.download( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\tracing\decorator.py", line 119, in wrapper_use_tracer return func(*args, **kwargs) ^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\storage\blob\_generated\operations\_blob_operations.py", line 1641, in download pipeline_response: PipelineResponse = self._client._pipeline.run( # pylint: disable=protected-access ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 242, in run return first_node.send(pipeline_request) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ [Previous line repeated 2 more times] File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\policies\_redirect.py", line 205, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\storage\blob\_shared\policies.py", line 555, in send raise err File "C:\Program Files\Python312\Lib\site-packages\azure\storage\blob\_shared\policies.py", line 527, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ [Previous line repeated 1 more time] File "C:\Program Files\Python312\Lib\site-packages\azure\storage\blob\_shared\policies.py", line 301, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 98, in send response = self.next.send(request) ^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\_base.py", line 130, in send self._sender.send(request.http_request, **request.context.options), ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\storage\blob\_shared\base_client.py", line 353, in send return self._transport.send(request, **kwargs) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "C:\Program Files\Python312\Lib\site-packages\azure\core\pipeline\transport\_requests_basic.py", line 409, in send raise error azure.core.exceptions.ServiceRequestError: <urllib3.connection.HTTPSConnection object at 0x00000222F95FA240>: Failed to resolve 'odsblobcontainer.blob.odsblobcontainer.blob.core.windows.net' ([Errno 11001] getaddrinfo failed)
问题根源与修复方案
1. 连接字符串格式错误
你的connection_string中EndpointSuffix字段包含了额外的路径/myproj,这会导致SDK生成错误的Blob服务域名(重复拼接容器名),触发解析失败。正确的EndpointSuffix应该仅为Blob服务的后缀,比如公有云Azure的core.windows.net。
2. 容器名称格式错误
Blob存储的容器名称不能包含斜杠,MyContainer/Prj1是错误格式,Prj1应该作为Blob路径的一部分,而非容器名称的一部分。
3. 工作表顺序控制问题
原脚本使用mode="a"追加工作表,无法保证tab1在最前、tab5在倒数第二的位置,需要读取所有原工作表后按指定顺序重新写入。
修正后的完整脚本
from azure.storage.blob import BlobServiceClient import pandas as pd from io import BytesIO from datetime import date today = date.today().strftime("%Y%m%d") # 修正连接字符串:EndpointSuffix仅保留服务后缀 connection_string = "DefaultEndpointsProtocol=https;AccountName=MyAccount;AccountKey=accountkey;EndpointSuffix=core.windows.net" # 修正容器与Blob路径:容器名仅为MyContainer,Prj1作为Blob路径前缀 container_name = "MyContainer" excel_blob_name = "Prj1/My Excel.xlsx" csv_blob_1_name = "Prj1/My_csv1_"+today+".csv" csv_blob_2_name = "Prj1/My_csv2_"+today+".csv" # 初始化Blob服务客户端 blob_service_client = BlobServiceClient.from_connection_string(connection_string) # 读取Blob中的Excel文件 excel_blob_client = blob_service_client.get_blob_client(container=container_name, blob=excel_blob_name) excel_blob_data = BytesIO(excel_blob_client.download_blob().readall()) # 读取原Excel的所有工作表,用于控制顺序 xls = pd.ExcelFile(excel_blob_data) sheet_dict = {sheet_name: xls.parse(sheet_name) for sheet_name in xls.sheet_names} # 读取第一个CSV文件 csv_blob_client_1 = blob_service_client.get_blob_client(container=container_name, blob=csv_blob_1_name) csv_blob_data_1 = BytesIO(csv_blob_client_1.download_blob().readall()) df_csv_1 = pd.read_csv(csv_blob_data_1) # 读取第二个CSV文件 csv_blob_client_2 = blob_service_client.get_blob_client(container=container_name, blob=csv_blob_2_name) csv_blob_data_2 = BytesIO(csv_blob_client_2.download_blob().readall()) df_csv_2 = pd.read_csv(csv_blob_data_2) # 按指定顺序组织工作表:tab1 -> 原tab2、tab3、tab4 -> tab5 -> tab6 new_sheets = [ ("tab1", df_csv_1), ("tab2", sheet_dict["tab2"]), ("tab3", sheet_dict["tab3"]), ("tab4", sheet_dict["tab4"]), ("tab5", df_csv_2), ("tab6", sheet_dict["tab6"]) ] # 写入新的Excel文件到内存流 output_excel = BytesIO() with pd.ExcelWriter(output_excel, engine="openpyxl") as excel_writer: for sheet_name, df in new_sheets: df.to_excel(excel_writer, sheet_name=sheet_name, index=False) # 将修改后的Excel文件上传回Blob存储 output_excel.seek(0) excel_blob_client.upload_blob(output_excel, overwrite=True)
内容的提问来源于stack exchange,提问作者Arty155
相关产品推荐
相关产品推荐

