【问题标题】:CS50 finance: RuntimeError: cannot start a transaction within a transactionCS50 财务:RuntimeError:无法在事务中启动事务
【发布时间】:2020-12-23 19:23:40
【问题描述】:

所以,我正在尝试做 CS50 金融任务,对于那些不知道它的人,它是一个烧瓶应用程序,你可以为股市报价并购买它们,无论如何我正在尝试设置一条路线允许用户购买报价股票市场,这里是出现问题的代码:

        # Adding the values into the purchases table
        try:
            db.execute("INSERT INTO purchases(user_id, company_symbol, name, shares, price, total_price, transaction_time) VALUES (:user_id, :symbol, :name, :shares, :price, :total_price, :transaction_time)",
                    user_id=user_id, symbol=quote["symbol"], name=quote["name"], shares=shares, price=quote["price"], total_price=total_price, transaction_time=transaction_time)
        except:
            value = db.execute("SELECT shares, price, total_price FROM purchases WHERE user_id = :user_id", user_id=user_id)
            for item in value:
                item["shares"] = item["shares"] + shares
                item["total_price"] = item["total_price"] + total_price
                db.execute("UPDATE purchases SET shares = :shares, price = :price, total_price = :total_price WHERE user_id = :user_id",
                            shares=item["shares"], price=quote["price"], total_price=item["total_price"], user_id=user_id)

    return render_template("bought.html")

try 部分中,我正在尝试将INSERT 的值添加到表购买中并且有效,问题出在expect 部分中,当用户已经购买了相同的报价时,会调用此部分,它的工作是 UPDATE 购买表中的值,但运行时会出错。

错误:

RuntimeError: cannot start a transaction within a transaction

这是完整的路线:

@app.route("/buy", methods=["GET", "POST"])
@login_required
def buy():
    """Buy shares of stock"""
    if request.method == "GET":
        return render_template("buy.html")
    else:
        # Getting the form values
        symbol = request.form.get("symbol")
        shares = float(request.form.get("shares"))
        quote = lookup(symbol)

        # Checking for iput errors
        if not symbol:
            return apology("MISSING SYMBOL")
        elif not shares:
            return apology("MISSING SHARES")
        elif quote == None:
            return apology("INVALID SYMBOL")

        # Cheking if affordable
        user_id = session["user_id"]
        user_wallet = db.execute("SELECT cash FROM users WHERE id = :user_id", user_id=user_id)
        total_price = quote["price"] * shares

        for wallet in user_wallet:
            if total_price > wallet['cash']:
                return apology("CAN'T AFFORD")

        # Getting the current time
        transaction_time = datetime.datetime.now()

        # Creating the purchases table if not exist
        db.execute("CREATE TABLE IF NOT EXISTS purchases (user_id INTEGER NOT NULL, company_symbol TEXT NOT NULL UNIQUE, name TEXT NOT NULL UNIQUE, shares NUMERIC NOT NULL, price NUMERIC NOT NULL, total_price NUMERIC NOT NULL,transaction_time datetime NOT NULL,FOREIGN KEY (user_id) REFERENCES users(id))")

        # Adding the values into the purchases table
        try:
            db.execute("INSERT INTO purchases(user_id, company_symbol, name, shares, price, total_price, transaction_time) VALUES (:user_id, :symbol, :name, :shares, :price, :total_price, :transaction_time)",
                    user_id=user_id, symbol=quote["symbol"], name=quote["name"], shares=shares, price=quote["price"], total_price=total_price, transaction_time=transaction_time)
        except:
            value = db.execute("SELECT shares, price, total_price FROM purchases WHERE user_id = :user_id", user_id=user_id)
            for item in value:
                item["shares"] = item["shares"] + shares
                item["total_price"] = item["total_price"] + total_price
                db.execute("UPDATE purchases SET shares = :shares, price = :price, total_price = :total_price WHERE user_id = :user_id",
                            shares=item["shares"], price=quote["price"], total_price=item["total_price"], user_id=user_id)

    return render_template("bought.html")

提前感谢您的帮助。

【问题讨论】:

  • 你的引号到处都是。尝试更正它们,以便在 db 中执行的部分只是一个字符串。也许使用'
  • 你能分享完整的回溯吗?
  • 购买表的主键是什么?抛出了什么异常?请注意,UPDATE 查询将更新购买表中 user_id 的 所有 记录。
  • purchasing 表没有主键 value user_id 是从另一个名为 users 的表中获取的 id 的值,如果我不能很好地解释它,我很抱歉只是一个初学者。

标签: python sql flask cs50


【解决方案1】:

这个“当用户已经购买了相同的报价时调用这个部分”是问题的核心。如果purchases 没有主键,系统无法知道用户已经购买了相同的报价。如果 INSERT 在 UNIQUENESS 约束上失败,则此代码可以正常工作。由于购买没有PK,它不可能在唯一性上失败,那么为什么插入失败?

最佳猜测:

  • 表未创建,因为它已经存在
  • 由于一些架构问题,插入失败,例如无效的列名

疑难解答:

  • except: 更改为except Exception as e:
  • 添加print(e)作为except块的第一行
  • 发生错误时,通过flask日志备份,看看抛出了什么异常
  • 根据需要更正问题

设计: 如果购买表旨在通过符号跟踪用户的持有量,则该表需要 user_id,symbol 上的主键。需要修改 UPDATE 以适应它(id WHERE user_id = sth AND symbol = sth)。

我无法从技术上解释运行时错误。这是界面的一个怪癖,可以通过纠正底层问题来纠正。

【讨论】:

    猜你喜欢
    • 2015-04-29
    • 2023-04-06
    • 1970-01-01
    • 2017-01-31
    • 2021-01-18
    • 2017-09-14
    • 1970-01-01
    • 1970-01-01
    • 2017-03-09
    相关资源
    最近更新 更多