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

使用Smartsheet Python SDK并发更新同表格遇4004错误的解决方法

问题:Smartsheet Python SDK并发更新行触发4004错误

使用Smartsheet Python SDK调用API更新表格行时,并发发起针对同一张表格不同行的更新请求,会触发以下内部服务器错误:

Process finished with exit code 0
{"response": {"statusCode": 500, "reason": "Internal Server Error", "content": {"errorCode": 4004, "message": "Request failed because sheetId ##### is currently being updated by another request that uses the same access token.  Please retry your request once the previous request has completed.", "refId": "####"}}}

触发错误的并发执行代码示例:

import smartsheet

SMARTSHEET_ACCESS_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXX"
smartsheet_client = smartsheet.Smartsheet(SMARTSHEET_ACCESS_TOKEN)
sheet = smartsheet_client.Sheets.get_sheet('XXXXXXXXXXXXXX')

column_map = {}
for column in sheet.columns:
    column_map[column.title] = column.id

row_map = {}
i = 0
for rows in sheet.rows:
    row_map[i] = rows.id
    i = i + 1

new_cell = smartsheet_client.models.Cell()
new_cell.column_id = column_map['Last End Time']
new_cell.value = '02/23/2023 12:13:57 AM'
new_cell.strict = False
get_row = smartsheet.models.Row()
get_row.id = row_map[int(5) - 1]
get_row.cells.append(new_cell)
api_response = smartsheet_client.Sheets.update_rows('xxxxxxxxxxxxxxxxxxxx', [get_row])
print(api_response)

请问如何使用Python SDK更新表格多行时避免该错误?


解决方案

1. 批量提交多行更新(最优方案)

Smartsheet API支持在单个update_rows请求中提交多行更新,这是官方推荐的方式,可完全避免并发冲突。将所有需要更新的行对象放入同一个列表,一次性发送请求。

示例代码(基于原有代码修改):

import smartsheet

SMARTSHEET_ACCESS_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXX"
smartsheet_client = smartsheet.Smartsheet(SMARTSHEET_ACCESS_TOKEN)
sheet = smartsheet_client.Sheets.get_sheet('XXXXXXXXXXXXXX')

# 简化映射构造
column_map = {col.title: col.id for col in sheet.columns}
row_map = {i: row.id for i, row in enumerate(sheet.rows)}

# 存储所有待更新行的列表
rows_to_update = []

# 构造第5行的更新
cell1 = smartsheet_client.models.Cell()
cell1.column_id = column_map['Last End Time']
cell1.value = '02/23/2023 12:13:57 AM'
cell1.strict = False
row1 = smartsheet.models.Row()
row1.id = row_map[4]  # 对应原代码的row_map[int(5)-1]
row1.cells.append(cell1)
rows_to_update.append(row1)

# 可继续添加更多行的更新
cell2 = smartsheet_client.models.Cell()
cell2.column_id = column_map['Last End Time']
cell2.value = '02/23/2023 01:15:30 AM'
cell2.strict = False
row2 = smartsheet.models.Row()
row2.id = row_map[9]  # 示例更新第10行
row2.cells.append(cell2)
rows_to_update.append(row2)

# 一次性提交所有更新请求
api_response = smartsheet_client.Sheets.update_rows(sheet.id, rows_to_update)
print(api_response)

2. 必须并发时实现重试机制

如果业务场景无法避免并发请求,需针对4004错误添加重试逻辑,捕获错误后等待一段时间再重新发起请求。

示例代码(带指数退避的重试逻辑):

import smartsheet
import time

SMARTSHEET_ACCESS_TOKEN = "XXXXXXXXXXXXXXXXXXXXXXX"
smartsheet_client = smartsheet.Smartsheet(SMARTSHEET_ACCESS_TOKEN)
sheet_id = 'xxxxxxxxxxxxxxxxxxxx'

def update_row_with_retry(row_obj, max_retries=3, initial_delay=2):
    delay = initial_delay
    for attempt in range(max_retries):
        try:
            return smartsheet_client.Sheets.update_rows(sheet_id, [row_obj])
        except smartsheet.exceptions.ApiError as e:
            if e.error_code == 4004:
                print(f"请求冲突,等待{delay}秒后重试...")
                time.sleep(delay)
                delay *= 2  # 指数退避,避免频繁重试
            else:
                # 非4004错误直接抛出
                raise
    raise Exception("重试次数耗尽,更新失败")

# 构造待更新行对象
sheet = smartsheet_client.Sheets.get_sheet(sheet_id)
column_map = {col.title: col.id for col in sheet.columns}
row_map = {i: row.id for i, row in enumerate(sheet.rows)}

new_cell = smartsheet_client.models.Cell()
new_cell.column_id = column_map['Last End Time']
new_cell.value = '02/23/2023 12:13:57 AM'
new_cell.strict = False
target_row = smartsheet.models.Row()
target_row.id = row_map[4]
target_row.cells.append(new_cell)

# 调用带重试的更新函数
response = update_row_with_retry(target_row)
print(response)

3. 调整客户端并发配置

检查并限制Smartsheet客户端的并发连接数,避免同一令牌下同时发起过多请求。可通过修改客户端的重试和超时参数,或调整底层HTTP连接池大小:

smartsheet_client = smartsheet.Smartsheet(SMARTSHEET_ACCESS_TOKEN)
# 调整客户端重试次数和超时时间
smartsheet_client.configuration.max_retries = 2
smartsheet_client.configuration.timeout = 10

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 20:39:19