sqlite3/tkinter如何使用数据库自带rowid删除TreeView对应行并解决报错
问题修复方案
你遇到的报错和功能实现问题有3个核心错误,按如下步骤修改即可:
错误原因
- SQL语句不完整:执行删除的SQL语句里
rowid =后面缺少参数占位符?,导致SQL语法不完整,直接触发incomplete input报错 - rowid获取逻辑错误:
c.lastrowid只能拿到当前数据库连接最近一次INSERT操作生成的行ID,和你当前在TreeView选中的记录毫无关联,你需要在插入TreeView数据时就把对应记录的SQLite rowid绑定到TreeView行上 - 参数格式错误:
sqlite3的execute方法第二个参数要求是序列,单元素需要写成(rowid,)(带末尾逗号),你写的(rowid)只是普通括号包裹变量,会被识别为单个值而非元组,传参不合法
完整修改代码
我补充了你缺失的TreeView初始化、数据库表创建、测试数据插入逻辑,你可以直接复用:
from tkinter import * from tkinter import ttk import sqlite3 app = Tk() app.geometry('1000x600') # 初始化数据库,仅首次运行需要,后续可以注释 conn = sqlite3.connect('CustomerRecords.db') c = conn.cursor() c.execute('''CREATE TABLE IF NOT EXISTS customers ( name TEXT, phone TEXT, email TEXT )''') # 插入测试数据 c.execute("INSERT INTO customers VALUES ('张三', '13800138000', 'zhangsan@test.com')") c.execute("INSERT INTO customers VALUES ('李四', '13900139000', 'lisi@test.com')") conn.commit() conn.close() # 创建按钮容器 button_frame = Frame(app) button_frame.pack(pady=20) # 创建TreeView my_tree = ttk.Treeview(app, columns=('name', 'phone', 'email'), show='headings') # 定义列 my_tree.heading('name', text='姓名') my_tree.heading('phone', text='电话') my_tree.heading('email', text='邮箱') my_tree.pack(pady=20) # 加载数据库数据到TreeView def load_data(): # 先清空TreeView for item in my_tree.get_children(): my_tree.delete(item) conn = sqlite3.connect('CustomerRecords.db') c = conn.cursor() # 查询的时候带上rowid,插入TreeView时把rowid作为行的iid c.execute("SELECT rowid, name, phone, email FROM customers") for row in c.fetchall(): # 把SQLite的rowid作为TreeView行的iid,方便后续删除时获取 my_tree.insert('', END, iid=row[0], values=(row[1], row[2], row[3])) conn.close() load_data() def remove_one(): # 获取选中行的iid,这个iid就是我们之前存的SQLite rowid selected_rowid = my_tree.selection()[0] # 先删TreeView里的行 my_tree.delete(selected_rowid) conn = sqlite3.connect('CustomerRecords.db') c = conn.cursor() # 补全SQL语句的占位符,参数用带逗号的元组 c.execute("DELETE from customers WHERE rowid = ?", (selected_rowid,)) conn.commit() conn.close() remove_one_button = Button(button_frame, text = 'Remove Record', command= remove_one) remove_one_button.grid(row =0, column=2, padx = 10, pady = 10) app.mainloop()
核心修改点说明
- 往TreeView插入数据时,把SQLite的rowid作为TreeView行的
iid属性存储,选中行时直接取selection()[0]就能拿到对应记录的rowid - 删除的SQL语句补全了
?占位符,参数修改为合法的单元素元组(selected_rowid,)
内容的提问来源于stack exchange,提问作者Zinnedd
相关产品推荐
相关产品推荐

