You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 10:54:18