Python3如何获取Smartsheet行并添加/更新到另一工作表指定位置
我一直在寻找标题中简要描述的场景对应的解决方案:我尝试通过smartsheet_client.Sheets.get_row()请求从一个工作表获取行数据,将其新增或更新到另一工作表的自定义位置,即可通过位置指定属性将行放置在非工作表末尾的位置。我已知可通过代码实现跨工作表复制粘贴行,但希望绕过“仅能复制到工作表末尾”的限制,想确认该需求是否可实现。
以下是我正在调试的代码:
row_a = smartsheet_client.Sheets.get_row( 2896510686914436, # sheet_id 6830091038549892, # row_id include='discussions,attachments,columns,columnType' ) row_a.sibling_id = 3539932199446404 #if row_a.isinstance('parent_id',int) #row_a.created_at = new_time #row_a.modified_at = new_time row_a.above = False #row_a.row_number = None #row_a.parent_id = None row_a.id = 7015416612448132 #id of new row # Add rows to sheet response = smartsheet_client.Sheets.update_rows_with_partial_success( 731362710841220, # sheet_id of sheets we are adding to [row_a] ) print("Done!") print(row_b)
调试遇到的问题
我最初的计划是调用get_row获取行对象后,为其添加目标位置对应的sibling_id和.above属性,再直接提交构建好的行对象完成新增,但收到了解析错误:
{"response": {"statusCode": 400, "reason": "Bad Request", "content": {"errorCode": 1008, "message": "Unable to parse request. The following error occurred: Field \"createdAt\" was of unexpected type.", "refId": "1eyronnlz32sw"}}}
之后我尝试将created_at属性设置为当前实时时间,又出现了modified_at相关报错;我以同样方式修正该字段后,又收到新的报错:
invalid row location: specify above or below with
siblingIdYou cannot use other location specifiers in the same request.
(行位置无效:需通过siblingId指定相对于目标位置的上下关系,同一请求中不可使用其他位置指定符)
后续无论我如何调整都无法成功,哪怕我将row_number、parent_id等“其他位置指定符”设为None,仍会收到报错提示:
"The attribute(s) row.id, row.createdAt, row.modifiedAt, row.columns[], row.sheetId, row.version, row.accessLevel are not allowed for this operation." (该操作不支持传入row.id、row.createdAt、row.modifiedAt、row.columns[]、row.sheetId、row.version、row.accessLevel属性)
目前始终未找到该操作的正确实现方式,求针对该场景的实现思路或通用开发建议。
这个需求完全可实现,所有报错的核心原因都是你直接把get_row返回的全量行对象传给了写入接口——Smartsheet的行查询接口会返回大量只读系统字段,这些字段是服务端自动生成维护的,不允许在写入请求里提交,直接复用全量对象必然触发各种类型、字段非法的报错。
正确实现步骤
- 不要直接复用查询返回的行对象,新建一个空白的
Row实例作为写入载体,只提取源行里的单元格值、格式等你需要的业务字段,不要带任何系统自动生成的属性。必须剔除的只读字段包括报错里提到的id、createdAt、modifiedAt、columns、sheetId、version、accessLevel,源行自带的rowNumber、parentId默认值也要清空,避免位置参数冲突。 - 位置参数只保留两个字段即可:
sibling_id填你要锚定的目标位置行ID,above传布尔值,True代表放到锚定行上方,False代表放到锚定行下方。不要同时传parent_id、row_number这类其他位置相关字段,否则会触发位置参数冲突报错。 - 如果需要携带源行的附件、讨论,不要直接在新增行时传
include返回的关联对象,先完成行新增拿到新行ID,再单独调用附件、讨论的复制接口关联到新行,避免嵌套对象类型不匹配。
修正后的核心代码参考
from smartsheet.models import Row, Cell # 1. 获取源行数据 source_row = smartsheet_client.Sheets.get_row( 2896510686914436, 6830091038549892, include='discussions,attachments,columns,columnType' ) # 2. 构建全新的目标行对象,只传入业务字段 target_row = Row() target_row.cells = [] for cell in source_row.cells: new_cell = Cell() new_cell.column_id = cell.column_id new_cell.value = cell.value # 需要保留单元格格式就放开下面这行注释 # new_cell.format_ = cell.format_ target_row.cells.append(new_cell) # 3. 仅设置需要的位置参数 target_row.sibling_id = 3539932199446404 target_row.above = False # 注意:不要手动设置id!新增行接口会自动生成新行ID,手动传固定ID会触发只读字段报错 # 4. 调用新增行接口(新增行用add_rows,不是update_rows,后者仅用于更新已存在的行) response = smartsheet_client.Sheets.add_rows( 731362710841220, [target_row] ) new_row_id = response.result[0].id # 5. 后续如果需要复制附件、讨论,在这里用new_row_id单独调用对应接口即可 print(f"行新增成功,新行ID:{new_row_id}")
额外注意点
- 你原代码最后打印的
row_b变量从未定义,本身也会触发运行错误。 - 如果要把行放到工作表最顶部,把
sibling_id设为工作表第一行的ID,above设为True即可,不需要特殊参数。 - 如果是要把行放到分层结构的指定父行下,单独设置
parent_id即可,此时不要再传sibling_id和above,两类位置参数不能混用。
内容的提问来源于stack exchange,提问作者SkipTP9

