Python+SQLite应用无法按rowid删除数据问题求助
问题根源
你遇到的删除无效问题,核心是展示的序号≠数据库真实rowid:
- 展示产品时用
enumerate(all_products,1)生成的是前端自增的展示序号,不是SQLite表中真实的rowid - 删除时错误地用这个展示序号去匹配
rowid,导致剩余产品的展示序号和真实rowid不匹配(比如剩余产品真实rowid是2,但展示序号是1,输入1去删rowid=1自然找不到数据)
修复方案
以下是修改后的完整代码,核心是让展示的ID和数据库真实rowid保持一致,同时优化输入验证和SQL安全性:
1. 修改数据库连接类(无需改动连接逻辑,只调整查询和展示)
import sqlite3 class Database: def __init__(self): self.existing_row_ids = [] # 存储当前存在的所有rowid,用于输入验证 self.latest_row_id = 0 self.connect_database() def connect_database(self): self.connect = sqlite3.connect("bike_rental.db") self.cursor = self.connect.cursor() self.cursor.execute( "CREATE TABLE IF NOT EXISTS products(name TEXT,speed TEXT,typ TEXT,stock INT,price INT)") self.connect.commit() def show_products(self): message = "Welcome, you can control products from this page".upper() print(message) print("-" * len(message)) # 查询时同时获取数据库真实的rowid self.cursor.execute("SELECT rowid, * FROM products") all_products = self.cursor.fetchall() convert_all_str = lambda x: [str(y) for y in x] print("ID Name Speed Type Stock Cost") # 遍历展示真实rowid和产品信息 for product in all_products: row_id = product[0] product_details = product[1:] print("-" * 75) print(f"{row_id} - {' '.join(convert_all_str(product_details))} TRY") print("-" * 75) # 更新现有rowid列表和最大rowid self.existing_row_ids = [p[0] for p in all_products] self.latest_row_id = max(self.existing_row_ids) if self.existing_row_ids else 0 return all_products def delete_products(self): while True: try: selected_row_id = int(input("Enter id of product you want to delete: ")) # 直接验证输入的ID是否存在于现有产品中 if selected_row_id not in self.existing_row_ids: print(f"\033[31mInvalid ID! Existing product IDs are: {', '.join(map(str, self.existing_row_ids))}\033[m") continue print("\033[1;32mYou have successfully deleted the selected product.\033[m") break except ValueError: print("\033[31mInvalid input! Please enter an integer number.\033[m") # 使用参数化查询避免SQL注入,同时匹配真实rowid self.cursor.execute("DELETE FROM products WHERE rowid = ?", (selected_row_id,)) self.connect.commit() # 删除后刷新产品列表,更新rowid信息 self.show_products()
2. 关键修改点说明
- 查询真实rowid:
SELECT rowid, * FROM products直接获取数据库中每条数据的真实rowid,展示给用户的ID就是实际要删除的ID - 输入验证优化:用
existing_row_ids列表验证输入的ID是否存在,避免无效输入 - SQL安全优化:把原来的f-string拼接SQL改成参数化查询(
?占位符),杜绝SQL注入风险 - 自动刷新列表:删除后调用
show_products(),实时更新展示的产品和rowid信息
内容的提问来源于stack exchange,提问作者Gurur
相关产品推荐
相关产品推荐

