新手技术问询:如何从MySQL数据库取数并在GUI中展示?
解决MySQL多表查询错误与CustomTkinter数据展示问题
一、修复MySQL多表查询的错误
你的报错根源是直接把Python UI控件的UPC_entry.get()方法写进了SQL语句——MySQL会将其识别为一个不存在的数据库函数,因此抛出错误。另外,用逗号直接连接三张表会产生笛卡尔积,导致查询结果混乱,必须通过JOIN结合reference表的关联逻辑来正确匹配数据。
正确实现步骤:
- 先获取输入框的内容并存储为变量
- 使用参数化查询(既避免SQL注入风险,也解决语法问题)
- 通过
JOIN关联三张表,利用reference表的字段匹配doitbest和truevalue的对应产品
示例代码:
# 先获取输入框的查询值 search_value = UPC_entry.get().strip() # 请根据reference表的实际关联字段调整JOIN条件,比如如果用SKU关联就替换PrimaryUPC query = """ SELECT db.Description AS doitbest_desc, db.Price AS doitbest_price, tv.Description AS truevalue_desc, tv.Price AS truevalue_price FROM reference r JOIN doitbest db ON r.doitbest_upc = db.PrimaryUPC JOIN truevalue tv ON r.truevalue_upc = tv.PrimaryUPC WHERE r.PrimaryUPC = %s """ # 执行参数化查询,参数以元组形式传入 mycursor.execute(query, (search_value,)) # 若查询结果唯一,用fetchone()更高效;若有多条结果,改用fetchall() myresult = mycursor.fetchone()
二、在CustomTkinter中展示对比数据
不用刻意模拟输入框,直接用分组框架+标签的方式展示,对比逻辑更清晰。可以创建两个并排的框架,分别承载Do-It Best和True Value的产品信息,每个框架内用标签展示字段名和对应数据。
示例代码:
import customtkinter as ctk # 初始化主窗口 root = ctk.CTk() root.title("五金产品价格对比") root.grid_columnconfigure((0,1), weight=1) # 创建两个并排的框架,用于分隔两个品牌的数据 frame_doitbest = ctk.CTkFrame(root) frame_doitbest.grid(row=0, column=0, padx=20, pady=20, sticky="nsew") frame_truevalue = ctk.CTkFrame(root) frame_truevalue.grid(row=0, column=1, padx=20, pady=20, sticky="nsew") # 添加框架标题 ctk.CTkLabel(frame_doitbest, text="Do-It Best 产品信息", font=ctk.CTkFont(size=16, weight="bold")).grid(row=0, column=0, columnspan=2, pady=10) ctk.CTkLabel(frame_truevalue, text="True Value 产品信息", font=ctk.CTkFont(size=16, weight="bold")).grid(row=0, column=0, columnspan=2, pady=10) # 定义数据展示函数 def display_product_data(result): # 清空之前的展示内容(可选,避免重复叠加) for widget in frame_doitbest.winfo_children()[1:]: widget.destroy() for widget in frame_truevalue.winfo_children()[1:]: widget.destroy() if not result: ctk.CTkLabel(frame_doitbest, text="无匹配产品").grid(row=1, column=0, padx=5, pady=5) ctk.CTkLabel(frame_truevalue, text="无匹配产品").grid(row=1, column=0, padx=5, pady=5) return # 展示Do-It Best的数据 ctk.CTkLabel(frame_doitbest, text="产品描述:").grid(row=1, column=0, sticky="w", padx=5, pady=5) ctk.CTkLabel(frame_doitbest, text=result[0]).grid(row=1, column=1, sticky="w", padx=5, pady=5) ctk.CTkLabel(frame_doitbest, text="售价:").grid(row=2, column=0, sticky="w", padx=5, pady=5) ctk.CTkLabel(frame_doitbest, text=f"${result[1]:.2f}").grid(row=2, column=1, sticky="w", padx=5, pady=5) ctk.CTkLabel(frame_doitbest, text="SKU:").grid(row=3, column=0, sticky="w", padx=5, pady=5) # 若需要展示SKU,可在查询语句中添加对应字段,这里假设是result[4] # ctk.CTkLabel(frame_doitbest, text=result[4]).grid(row=3, column=1, sticky="w", padx=5, pady=5) # 展示True Value的数据 ctk.CTkLabel(frame_truevalue, text="产品描述:").grid(row=1, column=0, sticky="w", padx=5, pady=5) ctk.CTkLabel(frame_truevalue, text=result[2]).grid(row=1, column=1, sticky="w", padx=5, pady=5) ctk.CTkLabel(frame_truevalue, text="售价:").grid(row=2, column=0, sticky="w", padx=5, pady=5) ctk.CTkLabel(frame_truevalue, text=f"${result[3]:.2f}").grid(row=2, column=1, sticky="w", padx=5, pady=5) # 查询完成后调用展示函数 # display_product_data(myresult) root.mainloop()
如果需要支持多条匹配结果,可以改用CTkScrollableFrame包裹所有标签,或者用CTkTextbox逐行打印数据。
内容的提问来源于stack exchange,提问作者user23604742
相关产品推荐
相关产品推荐

