使用QSqlDatabase将QTableWidget数据插入Ms Access无记录如何解决
问题排查与解决步骤
- 第一步:校验数据库连接有效性
你当前代码直接调用con.open()但没有判断返回结果,连接失败时后续逻辑不会执行也不会触发明显报错。需要先打印连接状态和错误信息:
if not con.open(): print("数据库连接失败:", con.lastError().text()) return
同时要确认系统安装的Access ODBC驱动位数和Python运行位数一致,32位Python只能用32位ODBC驱动,64位同理,不匹配时会静默连接失败。
- 第二步:校验getData返回的数据有效性
首先打印data的长度和内容,确认是否从表格中正确读取到了数据:
data = getData(self.tableWidgetInvoiceItem) print("读取到的数据条数:", len(data)) print("数据内容:", data)
如果data为空,说明表格读取逻辑有问题:检查QTableWidget是否存在空单元格,table.item(row, col)为空时直接调用.data()会触发异常,需要做空值判断:
def getData(table: QTableWidget) -> List[Tuple[str]]: data = [] for row in range(table.rowCount()): rowData = [] for col in range(table.columnCount()): item = table.item(row, col) # 空单元格补空字符串,避免报错 rowData.append(item.data(Qt.EditRole) if item else "") data.append(tuple(rowData)) return data
如果循环根本没有执行,自然不会生成插入记录。
- 第三步:校验插入执行结果
你当前只打印错误信息,但没有判断exec_()的返回值,插入失败时优先判断执行结果:
exec_result = insertDataQuery.exec_() if not exec_result: print("插入失败:", insertDataQuery.lastError().text()) else: print("插入成功,受影响行数:", insertDataQuery.numRowsAffected())
同时检查插入值的类型和数据库Test01表的字段类型是否匹配,比如数字类型字段传入了非数值格式的字符串,也会导致插入静默失败。
- 第四步:优化事务提交逻辑
你当前每次插入单条数据就执行一次con.commit(),可以调整为所有数据插入完成后统一提交,避免部分提交问题:
# 循环内只执行插入,不提交 for Quantity, ProductId, Description, Price, Tax, NetTotal, GrossTotal in data: # 绑定参数逻辑不变 insertDataQuery.addBindValue(Quantity) insertDataQuery.addBindValue(ProductId) insertDataQuery.addBindValue(Description) insertDataQuery.addBindValue(Price) insertDataQuery.addBindValue(Tax) insertDataQuery.addBindValue(NetTotal) insertDataQuery.addBindValue(GrossTotal) exec_result = insertDataQuery.exec_() # 错误判断逻辑不变 # 所有数据插入完成后统一提交 con.commit() # 最后关闭连接 con.close()
如果以上步骤都排查完成仍然插入失败,检查Access数据库文件是否处于被占用状态(比如手动打开了Access文件在编辑),数据库文件是否有写入权限,当前Windows用户是否对C:/Users/Egon/Documents/Invoice/路径有写入权限。
内容的提问来源于stack exchange,提问作者accpert.com
相关产品推荐
相关产品推荐

