Tkinter TreeView删除SQLite数据报错:sqlite3.OperationalError: no such column: I002
问题分析与解决
你的错误根源有两个:
- 传递错误参数给SQL语句:你在
cur.execute里传了selected_items(整个选中项列表)而非当前循环的selected_item;更关键的是,tree.selection()返回的是TreeView的节点ID(比如I002),这不是数据库里的mem_id,直接用它当条件会被SQLite当成列名,导致no such column: I002错误。 - 未从TreeView节点提取实际mem_id:你在
Read函数里把数据库的mem_id(即data[0])作为TreeView节点values的第一个元素,所以需要从选中节点中取出这个值作为删除条件。
修正后的Delete函数
def Delete(): selected_items = tree.selection() if not selected_items: txt_result.config(text="请选择要删除的项!", fg="red") return Database() cur = conn.cursor() # 循环外创建一次cursor即可 try: for selected_item in selected_items: # 获取选中节点的values,第一个元素就是mem_id mem_id = tree.item(selected_item)['values'][0] # 执行数据库删除,用mem_id作为条件 cur.execute("DELETE FROM anno WHERE mem_id = ?", (mem_id,)) # 删除TreeView中的节点 tree.delete(selected_item) conn.commit() txt_result.config(text="选中项已成功删除", fg="green") except Exception as e: conn.rollback() txt_result.config(text=f"删除失败:{str(e)}", fg="red") finally: cur.close() conn.close()
关键修改点说明
- 提取mem_id:用
tree.item(selected_item)['values'][0]获取节点对应的数据库mem_id,这才是和SQL表中mem_id匹配的值。 - 参数修正:SQL语句的参数改为
(mem_id,),注意逗号不能少,确保是元组类型(SQLite要求参数为序列类型)。 - 优化cursor创建:在循环外创建一次cursor,避免重复创建浪费资源。
- 增加异常处理:添加try-except-finally块,处理删除过程中的错误,防止数据库连接未关闭,同时给用户明确反馈。
- 空选择判断:先判断是否选中了项,避免无意义的执行。
内容的提问来源于stack exchange,提问作者Sarath kumar
相关产品推荐
相关产品推荐

