You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python中BrokenPipeError求助(gspread迁移谷歌表格数据)

使用gspread迁移14k行谷歌表格数据时触发BrokenPipeError的问题

问题背景

我在使用gspread将某谷歌表格中的14k行数据迁移至另一表格时,偶尔会触发BrokenPipeError: [Errno 32] Broken pipe错误。想请教这个错误是否和数据量大或网络连接不佳有关?有没有预防方法?

相关代码

worksheet1.values_clear("tc id!A:B")
source_tc= client.open('tc_sheet')
source_tc.sheet1.delete_row(1)
new_values_tc = source_tc.values_get('Sheet1!A:B')
worksheet1.values_update(
    "tc id!A:B" ,
    params={ 'valueInputOption': 'USER_ENTERED' } ,
    body={ 'values': new_values_tc['values'] }
)

完整错误日志

Traceback (most recent call last): File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py", line 672, in urlopen chunked=chunked, File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py", line 387, in _make_request conn.request(method, url, **httplib_request_kw) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 1252, in request self._send_request(method, url, body, headers, encode_chunked) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 1298, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 1247, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 1065, in _send_output self.send(chunk) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 987, in send self.sock.sendall(data) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1034, in sendall v = self.send(byte_view[count:]) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1003, in send return self._sslobj.write(data) BrokenPipeError: [Errno 32] Broken pipe During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/adapters.py", line 449, in send timeout=timeout File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py", line 720, in urlopen method, url, error=e, _pool=self, _stacktrace=sys.exc_info()[2] File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/util/retry.py", line 400, in increment raise six.reraise(type(error), error, _stacktrace) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/packages/six.py", line 734, in reraise raise value.with_traceback(tb) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py", line 672, in urlopen chunked=chunked, File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/urllib3/connectionpool.py", line 387, in _make_request conn.request(method, url, **httplib_request_kw) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 1252, in request self._send_request(method, url, body, headers, encode_chunked) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 1298, in _send_request self.endheaders(body, encode_chunked=encode_chunked) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 1247, in endheaders self._send_output(message_body, encode_chunked=encode_chunked) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 1065, in _send_output self.send(chunk) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/http/client.py", line 987, in send self.sock.sendall(data) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1034, in sendall v = self.send(byte_view[count:]) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/ssl.py", line 1003, in send return self._sslobj.write(data) urllib3.exceptions.ProtocolError: ('Connection aborted.', BrokenPipeError(32, 'Broken pipe')) During handling of the above exception, another exception occurred: Traceback (most recent call last): File "/Users/ali.ugurlu/Documents/gsheets/main.py", line 161, in <module> 'values': new_values_tc['values'] File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/gspread/models.py", line 176, in values_update r = self.client.request('put', url, params=params, json=body) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/gspread/client.py", line 73, in request headers=headers File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/sessions.py", line 593, in put return self.request('PUT', url, data=data, **kwargs) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/sessions.py", line 533, in request resp = self.send(prep, **send_kwargs) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/sessions.py", line 646, in send r = adapter.send(request, **kwargs) File "/usr/local/Cellar/python/3.7.5/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/requests/adapters.py", line 498, in send raise ConnectionError(err, request=request) requests.exceptions.ConnectionError: ('Connection aborted.', BrokenPipeError(32, 'Broken pipe'))

回答

错误原因分析

没错,这个BrokenPipeError确实和数据量大以及网络连接稳定性直接相关:

  • 一次性传输14k行数据时,请求体体积会比较大,谷歌API服务器可能因负载过高或超时提前关闭连接;
  • 不稳定的网络环境下,数据传输过程中连接中断也会触发该错误——本质是客户端还在往已经被服务器关闭的连接写数据。

预防和解决方法

这里有几个实用的方案,按优先级推荐:

1. 分批传输数据

把14k行数据拆分成小批量(比如每次500-1000行),分多次调用values_update。这样每个请求的体积变小,既不容易触发服务器的连接限制,也降低了网络波动的影响。示例代码:

worksheet1.values_clear("tc id!A:B")
source_tc = client.open('tc_sheet')
source_tc.sheet1.delete_row(1)
new_values_tc = source_tc.values_get('Sheet1!A:B')['values']

# 分批处理,每批1000行
batch_size = 1000
for i in range(0, len(new_values_tc), batch_size):
    batch = new_values_tc[i:i+batch_size]
    # 计算目标范围,比如A1:B1000,A1001:B2000等
    start_row = i + 1
    end_row = i + len(batch)
    range_str = f"tc id!A{start_row}:B{end_row}"
    worksheet1.values_update(
        range_str,
        params={'valueInputOption': 'USER_ENTERED'},
        body={'values': batch}
    )

2. 添加重试机制

针对网络波动导致的偶发错误,添加带指数退避的重试逻辑。gspread底层用的是requests库,可以结合tenacity实现:

from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
import requests

# 定义重试装饰器,针对连接错误重试3次,每次等待时间指数增长
@retry(
    stop=stop_after_attempt(3),
    wait=wait_exponential(multiplier=1, min=2, max=10),
    retry=retry_if_exception_type((requests.exceptions.ConnectionError, BrokenPipeError))
)
def update_values_with_retry(worksheet, range_str, values):
    worksheet.values_update(
        range_str,
        params={'valueInputOption': 'USER_ENTERED'},
        body={'values': values}
    )

# 使用这个重试函数替代直接调用values_update
update_values_with_retry(worksheet1, "tc id!A:B", new_values_tc['values'])

3. 调整请求超时时间

默认的超时时间可能不够,你可以在创建gspread客户端时设置更长的超时时间,给大体积请求足够的传输时间:

from gspread import Client
import requests

# 自定义会话,设置超时
session = requests.Session()
session.timeout = 30  # 30秒超时,可根据实际情况调整
client = Client(auth, session=session)

4. 优化网络环境

如果是本地运行脚本,尽量连接稳定的网络;如果是服务器上运行,确保服务器到谷歌API的网络链路通畅,必要时可考虑使用合规的代理服务。

内容的提问来源于stack exchange,提问作者zeppelin11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:45:35