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

Flask中Session读取突然失效,触发Key Error问题求助

Flask Session 读取触发KeyError问题解决

问题概述

开发计算机课程预订网站时,使用Flask Session在两个页面间传递预订数据,已通过日志确认数据存入第一个路由的Session,但在第二个路由读取时触发KeyError,无法获取数据。

相关代码

@app.route("/manager/editbooking", methods=["POST", "GET"])
def managereditbooking():
    if request.method == "POST":

        if "Filter" in request.form != "Filter":

            StartDate = request.form.get("StartDate")
            EndDate = request.form.get("EndDate")
            Filter = request.form.get("Filter")

            app.logger.info(f"{StartDate} {EndDate} {Filter}")

            if Filter == "all" and StartDate and EndDate:
                # Filter by date range
                getactivebookings = f"SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.Extra, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Booking.Date BETWEEN '{StartDate}' AND '{EndDate}' ORDER BY Booking.Date ASC"
            elif Filter != "all" and StartDate and EndDate:
                # Filter by type and date range

                getactivebookings = f"SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults , Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Session.SessionType = '{Filter}' AND Booking.Date BETWEEN '{StartDate}' AND '{EndDate}' ORDER BY Booking.Date ASC"
            elif Filter != "all":
                # Filter by type only
                if  Filter == "Private Hire":
                    getactivebookings = "SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults , Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Session.SessionID = 8 OR Session.SessionID = 9 OR Session.SessionID = 10 ORDER BY Booking.Date ASC"
                else:
                    getactivebookings = f"SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults , Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Session.SessionType = '{Filter}' ORDER BY Booking.Date ASC"
            elif StartDate and EndDate:
                # Filter by date range only
                getactivebookings = f"SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID WHERE Booking.Date BETWEEN '{StartDate}' AND '{EndDate}' ORDER BY Booking.Date ASC"
            else:
                getactivebookings = "SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID ORDER BY Booking.Date ASC"

            app.logger.info(getactivebookings)
            q.execute(getactivebookings)
            activebookings = q.fetchall()

            return render_template("manager/selectbooking.html", activebookings=activebookings)

        else:

            app.logger.info("Redirecting to booking page")

            BookingID = request.form["BookingID"]
            BookingDate = request.form["BookingDate"]
            BookingTime = request.form["BookingTime"]
            SessionType = request.form["SessionType"]
            Extra = request.form["Extra"]
            BookingPrice = request.form["BookingPrice"]
            NumberAdults = request.form["NumberAdults"]
            NumberChildren = request.form["NumberChildren"]
            FirstName = request.form["FirstName"]
            LastName = request.form["LastName"]

            session["BookingID"] = BookingID
            session["BookingPrice"] = BookingPrice
            session["BookingDate"] = BookingDate
            session["BookingTime"] = BookingTime
            session["SessionType"] = SessionType
            session["NumberAdults"] = NumberAdults
            session["NumberChildren"] = NumberChildren
            session["Extra"] = Extra
            session["FirstName"] = FirstName
            session["LastName"] = LastName

            return redirect(url_for("managerbooking"))

    else:
        try:

            getactivebookings = "SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, Booking.NumberOfAdults, Customer.FirstName, Customer.LastName FROM Booking INNER JOIN Session ON Booking.SessionID = Session.SessionID INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID ORDER BY Booking.Date ASC"
            q.execute(getactivebookings)
            activebookings = q.fetchall()

            app.logger.info(activebookings)

            return render_template("manager/selectbooking.html", activebookings=activebookings)

        except Exception as error:
            return render_template("error.html", error=error)

@app.route("/manager/managebooking/booking", methods=["POST", "GET"])
def managerbooking():

    BookingID = session["BookingID"]
    BookingDate = session["BookingDate"]
    BookingTime = session["BookingTime"]
    SessionType = session["SessionType"]
    Extra = session["Extra"]
    BookingPrice = session["BookingPrice"]
    NumberAdults = session["NumberAdults"]
    NumberChildren = session["NumberChildren"]
    FirstName = session["FirstName"]
    LastName = session["LastName"]

    if request.method == "POST":

        app.logger.info(f"Deleting Booking with Booking ID: {BookingID}")

        DeleteBooking = "DELETE FROM Booking WHERE BookingID = (?)"

        try:
            q.execute(DeleteBooking, [BookingID])
            sql.commit()
            app.logger.info("Booking Deleted Succesfully")

            return redirect(url_for("managereditbooking"))

        except Exception as error:
            return render_template("/error.html", error=error)

    else:

        return render_template("manager/booking.html", BookingID = BookingID, BookingDate = BookingDate, BookingTime = BookingTime, Extra = Extra, SessionType = SessionType, BookingPrice = BookingPrice, NumberAdults = NumberAdults, NumberChildren = NumberChildren, FirstName = FirstName, LastName = LastName)

解决步骤

1. 确认SECRET_KEY配置

Flask Session依赖SECRET_KEY进行加密存储,没有配置的话Session数据无法持久化。在Flask应用初始化时添加:

import secrets
app.secret_key = secrets.token_hex(16)  # 生成安全的随机密钥

生产环境要将密钥存入环境变量,不要硬编码到代码中。

2. 强制标记Session修改

在存入Session数据后,手动设置session.modified = True确保数据被保存到会话中,避免重定向时数据丢失:

# 在重定向前添加
session["LastName"] = LastName
session.modified = True  # 新增这行
return redirect(url_for("managerbooking"))

3. 检查键名一致性

确认存入和读取Session的键名完全一致,比如session["BookingID"]和读取时的session["BookingID"],注意大小写和拼写,避免因键名错误触发KeyError。

4. 验证Cookie可用性

Flask Session通过Cookie传递会话ID,检查浏览器是否禁用了Cookie,测试时使用同一个浏览器窗口,不要开启隐私模式。

5. 防御SQL注入(额外建议)

当前代码使用字符串拼接SQL语句,存在严重的SQL注入风险,即使先实现功能,也建议尽快改用参数化查询,示例:

# 替换原字符串拼接的SQL
getactivebookings = """
    SELECT Booking.BookingID, Booking.Date, Booking.Time, Session.SessionType, 
           Booking.ExtraNotes, Booking.Price, Booking.NumberOfChildren, 
           Booking.NumberOfAdults, Customer.FirstName, Customer.LastName 
    FROM Booking 
    INNER JOIN Session ON Booking.SessionID = Session.SessionID 
    INNER JOIN Customer ON Booking.CustomerID = Customer.CustomerID 
    WHERE Session.SessionType = ? AND Booking.Date BETWEEN ? AND ? 
    ORDER BY Booking.Date ASC
"""
q.execute(getactivebookings, (Filter, StartDate, EndDate))

内容的提问来源于stack exchange,提问作者Ben Mercer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 19:55:54