将Tkinter输入框内容写入SQLite数据库时遇错误求助
解决SQLite插入数据时的TypeError及其他问题
核心错误原因
你遇到的TypeError: unsupported operand type(s) for %: 'sqlite3.Cursor' and 'tuple',是因为SQL语句的参数传递方式完全错误:你把字符串格式化的%操作放在了cur.execute()方法外面,导致试图让Cursor对象和元组做%运算,这是不被支持的。同时代码里还有其他多处问题,以下是完整修复方案:
问题点逐一修复
修正SQL参数传递方式
SQLite官方推荐用?作为占位符,将参数作为execute()的第二个参数传递,既避免语法错误,又能防止SQL注入。
错误写法:cur.execute("insert into player_stats values('%s', '%s', '%s', '%s', '%s', '%s')") \ %(first_name.get(), points.get(), assists.get(), rebounds.get(), shots_made.get(), shots_missed.get())正确写法:
cur.execute("INSERT INTO player_stats VALUES (?, ?, ?, ?, ?, ?)", (first_name.get(), points.get(), assists.get(), rebounds.get(), shots_made.get(), shots_missed.get()))Entry组件绑定变量
你定义了first_name、points等StringVar/IntVar,但没有将它们绑定到对应的Entry组件,导致get()无法获取用户输入。每个Entry都要添加textvariable参数:
示例:player_name = Entry(root, width=10, textvariable=first_name) entry_points = Entry(root, width=10, textvariable=points)修复未定义的
top变量
代码中使用了top但未创建,直接替换为已定义的root即可。修复语法错误
shots_made_label的Entry代码缺少闭合括号,补充完整并绑定变量:shots_made_label = Entry(root, width=10, textvariable=shots_made)移除无效的
fetchall()调用INSERT语句不会返回查询结果,且你在调用fetchall()前已经关闭了连接,同时fetchall()是Cursor对象的方法,不是Connection的,直接删除该语句。添加状态显示Label
定义了status变量但没有对应的显示控件,添加一个Label来展示成功提示:status_label = Label(root, textvariable=status, bg="light blue") status_label.place(x=300, y=320)
完整修复后的代码
from tkinter import ttk import sqlite3 from tkinter import * root = Tk() root.title("Player Statistics DBMS") root.geometry('700x400') root.config(bg="light blue") # 初始化数据库表 conn = sqlite3.connect('player_stats.db') cur = conn.cursor() cur.execute("""CREATE TABLE IF NOT EXISTS player_stats ( first_name text, points integer, assists integer, rebounds integer, shots_made integer, shots_missed integer)""") conn.commit() cur.close() conn.close() # 定义绑定变量 first_name = StringVar() points = IntVar() assists = IntVar() rebounds = IntVar() shots_made = IntVar() shots_missed = IntVar() status = StringVar() # 界面控件 player_name_label = Label(root, text='Player First Name:', bg="light blue") player_name_label.place(x=290, y=20) player_name_entry = Entry(root, width=10, textvariable=first_name) player_name_entry.place(x=300, y=50) points_label = Label(root, text="Number of Points:", bg="light blue") points_label.place(x=37, y=100) entry_points = Entry(root, width=10, textvariable=points) entry_points.place(x=45, y=130) assist_label = Label(root, text="Number of Assists:", bg="light blue") assist_label.place(x=192, y=100) entry_assists = Entry(root, width=10, textvariable=assists) entry_assists.place(x=207, y=130) rebound_label = Label(root, text="Number of Rebounds:", bg="light blue") rebound_label.place(x=350, y=100) entry_rebounds = Entry(root, width=10, textvariable=rebounds) entry_rebounds.place(x=369, y=130) # 注意:原代码中的turnovers字段不在数据库表中,这里保留控件但不处理,可根据需求修改表结构 turnovers_label = Label(root, text="Number of Turnovers:", bg="light blue") turnovers_label.place(x=520, y=100) turnovers_entry = Entry(root, width=10) turnovers_entry.place(x=541, y=130) shots_made_label = Label(root, text="Number of Shots Made:", bg="light blue") shots_made_label.place(x=106, y=200) shots_made_entry = Entry(root, width=10, textvariable=shots_made) shots_made_entry.place(x=129, y=230) shots_missed_label = Label(root, text="Number of Shots Missed:", bg="light blue") shots_missed_label.place(x=440, y=200) shots_missed_entry = Entry(root, width=10, textvariable=shots_missed) shots_missed_entry.place(x=465, y=230) # 状态显示 status_label = Label(root, textvariable=status, bg="light blue") status_label.place(x=300, y=320) def get(): try: conn = sqlite3.connect('player_stats.db') cur = conn.cursor() # 用?占位符传递参数 cur.execute("INSERT INTO player_stats VALUES (?, ?, ?, ?, ?, ?)", (first_name.get(), points.get(), assists.get(), rebounds.get(), shots_made.get(), shots_missed.get())) conn.commit() status.set("Data Entered Successfully") except Exception as e: status.set(f"Error: {str(e)}") finally: cur.close() conn.close() enter_data_button = Button(root, text="Enter", command=get) enter_data_button.place(x=336, y=280) root.mainloop()
额外说明
- 移除了无用的
mysql.connector导入 - 给控件变量重命名,避免Label和Entry变量重名导致覆盖
- 添加了异常捕获,方便查看插入失败的原因
- 原代码中的
turnovers字段不在数据库表中,若需要存储该数据,请修改CREATE TABLE语句添加对应字段
内容的提问来源于stack exchange,提问作者nightcat1325
相关产品推荐
相关产品推荐

