Python SQLite3中匹配用户输入ID查询数据生成Matplotlib报表的问题
解决Matplotlib报表按类别ID过滤数据的问题
看起来你已经搭好了基础的报表框架,但还没把用户输入的Category ID和数据库查询关联起来对吧?我来帮你修复这个问题,让报表能精准展示用户选择的类别数据:
当前代码的核心问题
你现在的SQL查询是拉取tblFinance里所有的CategoryID和AmountSpent,完全没有用到用户输入的id_input,所以不管用户输入什么ID,都会显示全类别的数据,这显然不是你想要的效果。
修复方案及代码示例
下面是修改后的完整代码,我加入了输入验证、参数化查询、空结果处理,还优化了报表的可读性:
if report_option == "A": print("Expense Report by Category: \n") # 先展示所有可用的类别(ID+名称),方便用户选择 c.execute("SELECT CategoryID, CategoryName FROM tblCategory") print("Available Categories:") for row in c.fetchall(): print(f"ID: {row[0]}, Name: {row[1]}") # 处理用户输入:确保是有效数字ID try: id_input = int(input("\nPlease enter the ID of the Category you would like to view: \n")) except ValueError: print("Oops! Please enter a numeric Category ID.") menu() return # 用参数化查询过滤指定类别的支出数据(避免SQL注入,同时精准匹配) # 假设tblFinance有TransactionDate字段用于展示支出趋势,没有的话可以去掉该字段 c.execute('SELECT TransactionDate, AmountSpent FROM tblFinance WHERE CategoryID = ?', (id_input,)) expense_records = c.fetchall() # 处理无数据的情况 if not expense_records: print(f"No expense records found for Category ID {id_input}.") menu() return # 提取绘图所需的数据 transaction_dates = [record[0] for record in expense_records] spent_amounts = [record[1] for record in expense_records] # 生成更友好的报表 plt.figure(figsize=(10, 6)) plt.plot(transaction_dates, spent_amounts, marker='o', linestyle='-', color='#2e86ab') plt.ylabel('Amount Spent') plt.xlabel('Transaction Date') # 获取类别名称,让报表标题更清晰 c.execute('SELECT CategoryName FROM tblCategory WHERE CategoryID = ?', (id_input,)) category_name = c.fetchone()[0] plt.title(f'Expense Report: {category_name} (ID: {id_input})') # 旋转日期标签,避免重叠 plt.xticks(rotation=45) plt.tight_layout() # 自动调整布局,防止标签被截断 plt.show() menu()
关键改进点说明
- 参数化查询:用
?占位符传递用户输入的ID,既避免了SQL注入风险,又能精准匹配数据库中的类别 - 输入验证:通过
try-except确保用户输入的是有效数字,避免程序崩溃 - 用户体验优化:先展示所有可用类别,用户不用凭空记ID;无数据时给出明确提示
- 报表可读性提升:加入类别名称作为标题、旋转日期标签、调整图表尺寸,让报表更直观
内容的提问来源于stack exchange,提问作者Keez
相关产品推荐
相关产品推荐

