首页 > 解决方案 > 相同的 Python SQLite3 查询为一个而不是另一个提供 IndexError

问题描述

我正在为我的最终 CS50 项目在 CS50 IDE 中使用 jQuery、Flask 和 SQLite3 开发一个 Web 应用程序。我的一个网页根据存储在数据库中的序列号按降序显示 SQL 数据库中的项目列表。网页在每个项目旁边都有按钮,用户可以单击这些按钮在列表中向上或向下移动项目。单击其中一个按钮会触发对 Flask 路由的 AJAX 调用,该路由检查数据库中项目的序列号并将其与相关相邻项目的序列号交换。完成此操作后,将使用 AJAX 以更新的顺序重新加载列表。

在 Flask 路由中,用于向上或向下移动项目的序列号的 Python 代码本质上是相同的,唯一的区别是给出的数字是 -1(在序列中向上移动)还是 +1(在序列中向下移动) )。见下文:

烧瓶路线

@app.route("/shift-unit-sequence", methods=["GET", "POST"])
def shiftUnitSequence():
    unit = request.form.get("unit")
    direction = request.form.get("direction")
    project = request.form.get("project")

    if direction == "u": # up (reduce sequence number)
        queryone = db.execute("SELECT sequence FROM units WHERE id = ?", unit)
        current = queryone[0]["sequence"]
        target = current - 1
        querytwo = db.execute("SELECT id FROM units WHERE sequence = ? AND project_id = ?", target, project)
        otherunit = querytwo[0]["id"]
        db.execute("UPDATE units SET sequence = ? WHERE id = ?", target, unit)
        db.execute("UPDATE units SET sequence = ? WHERE id = ?", current, otherunit)
        return ("", 204)

    if direction == "d": # down (increase sequence number)
        queryone = db.execute("SELECT sequence FROM units WHERE id = ?", unit)
        current = queryone[0]["sequence"]
        target = current + 1
        querytwo = db.execute("SELECT id FROM units WHERE sequence = ? AND project_id = ?", target, project)
        otherunit = querytwo[0]["id"]
        db.execute("UPDATE units SET sequence = ? WHERE id = ?", target, unit)
        db.execute("UPDATE units SET sequence = ? WHERE id = ?", current, otherunit)
        return ("", 204)

    return ("", 204)

出于某种原因,单击向下箭头(即,如果方向 ==“d”)完美无缺(序列号在数据库中更新,AJAX 调用完成,网页上的列表以新序列刷新),但单击向上箭头会产生以下错误:

File "/home/ubuntu/pset10/hobby/application.py", line 327, in shiftUnitSequence
current = queryone[0]["sequence"]
IndexError: list index out of range

这对我来说很莫名其妙。有问题的行与“down”代码中的等效行(下面的 10 行,第 337 行)相同,不会导致任何错误。错误描述表明上一行的 SQL 查询('queryone')返回的结果少于 1 个,使得 queryone[0] 超出范围,但是当我在 SQLite3 中手动运行此查询(例如SELECT sequence FROM units WHERE id = 4;)时,我得到了预期的结果结果 - 显示单元 4 的序列号的单行。为什么 Python 认为 queryone[0] 的第一行超出范围?此外,为什么 Python 认为 queryone[0] 在“向下”代码的范围内但在“向上”代码中超出范围?我已经看了两个多小时,无法弄清楚为什么第 327 行导致 IndexError 而第 337 行没有。

我尝试将 Flask 路由拆分为两个单独的路由(一个用于向上,一个用于向下)并修改我的 Javascript AJAX 函数以根据按下的按钮发布到适当的向上/向下路由,但同样的事情发生了(向下路由工作,上行路线产生 IndexErrorcurrent=queryone[0]["sequence"]在线)。我尝试交换“向上”和“向下”代码,因此 if 条件首先检查方向 ==“d”,但这也给出了相同的结果(“向下”工作正常,“向上”在相同的情况下产生 IndexError线)。我尝试用“down”代码完全覆盖“up”代码,然后更改唯一不同的部分(“current - 1”而不是“current + 1”),以防“up”中出现某种拼写错误'

如果有人能帮助解释这里发生了什么,以及如何解决这个错误,我将不胜感激。关于如何自己调试此类错误的提示也将不胜感激,因为我对编程和我常用的调试方法(重读代码十几次,检查变量值,将代码拆分成更小的块)相当陌生为了隔离问题,搜索在 Stack Overflow 上发布的类似问题)在这种情况下陷入了死胡同。

如果有帮助,我已经复制了将 AJAX 数据发布到有问题的 Flask 路由的 Javascript 函数下方。

JS函数

function shiftSequence(event) {
    var btnId = $(this).attr("id");
    var unitId = btnId.substring(8);  //id is in format 'shift-u-{unit.id}' or 'shift-d-{unit.id}'
    var dir = btnId.substring(6,7);
    var headerId = $("h1").attr("id");
    var projectId = headerId.substring(8);  //id is in format 'project-{project.id}'
    var sequenceId = $(this).parent().attr("id");
    var sequence = sequenceId.substring(6);  //id is in format 'shift-{unit.sequence}'
    var totalUnitsId = $(this).parent().parent().parent().parent().parent().attr("id");
    var totalUnits = totalUnitsId.substring(14);  //id is in format 'project-units-{project.units}'

    if (sequence == 1 && dir == "u") {  //cancel if unit is already at top and up arrow has been pressed
        return;
    } else if (sequence == totalUnits && dir == "d") { //cancel if unit is already at bottom and down arrow has been pressed
        return;
    }

    var postShiftUnit = $.post("/shift-unit-sequence", {
        unit: unitId,
        direction: dir,
        project: projectId
    });
    postShiftUnit.done(reloadUnits);
}

标签: pythonsqlite

解决方案


推荐阅读