Polarion API:如何通过单次操作批量更新工作项
问题描述
我写了个脚本用来更新Polarion文档里的工作项,但现在每个工作项都是单独保存的。因为脚本要更新文档里所有工作项,导致API产生大量保存操作,历史记录变得很乱。手动编辑Polarion文档时可以一次性更新所有工作项,想问下能不能通过Polarion API实现同样的操作?
已尝试的方法
- 使用Tracker Service更新工作项,但该服务只支持单条更新;
- 通过网页开发工具查看API调用信息,发现用了UniversalService,但这个服务在官方API站点没有可用文档。
更新1
我现在用python-polarion包更新工作项,按照@boaz的回答写了下面的代码:
project = client.getProject(project_name) doc = project.getDocument(document_location) workitems = doc.getWorkitems() session_service = client.getService("Session") tracker_service = client.getService("Tracker") session_service.beginTransaction() for workitem in workitems: workitem.description = workitem._polarion.TextType( content=str(datetime.datetime.now()), type='text/html', contentLossy=False) update_list = { "uri": workitem.uri, "description": workitem.description } tracker_service.updateWorkItem(update_list) session_service.endTransaction(False)
@boaz提到的登录步骤已经在后端完成了,但运行代码时抛出了Java异常:
java.lang.RuntimeException: java.lang.NullPointerException
更新2
会话好像有问题。执行这段代码:
session_service.logIn(user, password) print(session_service.hasSubject())
输出是False。
执行事务相关代码时:
session_service.beginTransaction() print(session_service.transactionExists())
输出也是False。
解决方案
问题根源
核心问题是Session服务未正确初始化会话,导致事务无法开启,批量更新逻辑失效。python-polarion的默认登录逻辑可能没有将会话绑定到你获取的Session Service实例上。
修复步骤
显式绑定会话
不要依赖后端自动登录,直接在代码中完成登录并校验状态,确保会话生效:session_service = client.getService("Session") # 显式执行登录操作 session_service.logIn(user, password) # 验证登录状态 assert session_service.hasSubject(), "登录失败,请检查账号密码"修正事务内更新逻辑
直接修改workitem对象后调用save(),比构造update_list更可靠,同时确保所有操作在事务内执行:session_service.beginTransaction() try: assert session_service.transactionExists(), "事务未成功开启" for workitem in workitems: workitem.description = workitem._polarion.TextType( content=str(datetime.datetime.now()), type='text/html', contentLossy=False) workitem.save() # 提交事务,所有更新一次性生效 session_service.endTransaction(True) except Exception as e: # 回滚事务,避免部分更新残留 session_service.endTransaction(False) raise e替代方案:用UniversalService批量更新
虽然官方文档未公开,但该服务支持批量打包操作,底层会自动处理一次性提交,历史记录仅生成一条:universal_service = client.getService("UniversalService") batch_ops = [] for workitem in workitems: update_data = { "uri": workitem.uri, "description": workitem._polarion.TextType( content=str(datetime.datetime.now()), type='text/html', contentLossy=False) } # 构造TrackerService.updateWorkItem的批量请求 batch_ops.append({ "service": "Tracker", "method": "updateWorkItem", "parameters": [update_data] }) # 执行批量操作 universal_service.executeBatch(batch_ops)
注意事项
- 所有Service实例必须从同一个客户端对象获取,避免会话隔离;
- 批量更新前先做小范围测试,防止误操作大量工作项;
- 使用事务时必须处理异常回滚,避免数据不一致。
内容的提问来源于stack exchange,提问作者Sybren Zwetsloot
相关产品推荐
相关产品推荐

