【问题标题】:Error in Flask Web App in Python: pymysql.err.ProgrammingError: Cursor closedPython 中 Flask Web App 中的错误:pymysql.err.ProgrammingError: Cursor closed
【发布时间】:2020-10-12 22:21:26
【问题描述】:

我似乎无法弄清楚我在烧瓶 Web 应用程序中收到“pymysql.err.ProgrammingError: Cursor closed”的错误。我确定我犯了一个小错误,但是关于这个错误的文档并不多。错误发生在“cursor.execute(query, email)”行。以下是我的代码:

from flask import Flask, render_template, request
import pymysql.cursors
import os

app = Flask(__name__)
IMAGES_DIR = os.path.join(os.getcwd(), "images")

conn = pymysql.connect(host='localhost',
                       port=8889,
                       user='LandingPage',
                       password='t9ybKLtVaS6qLQ7g',
                       db='LandingPage',
                       charset='utf8mb4',
                       cursorclass=pymysql.cursors.DictCursor)

@app.route('/', methods=['GET', 'POST'])
@app.route('/home', methods=['GET', 'POST'])
def home():
    if request.form:
        name = request.form['name']
        email = request.form['email']
        phone_number = request.form['phone number']

        with conn.cursor() as cursor:
            query = 'SELECT * FROM LandingPage WHERE email = %s'
            cursor.execute(query, email)
            data = cursor.fetchone()
            conn.commit()
        error = None
        if data:
            error = "A person with this email already exists in the database"
            return render_template('home.html', error=error)
        else:
            ins = "INSERT INTO LandingPage (name, email, phone number) VALUES (%s, %s, %s)"
            cursor.execute(ins, (name, email, phone_number))
            conn.commit()
            cursor.close()
            return render_template('home.html')
    return render_template('home.html')


if __name__ == "__main__":
    app.run('127.0.0.1', 4999, debug=True)

【问题讨论】:

  • 错误来自哪一行?
  • @Sam 对不起,我应该澄清一下 - 这个主页在 localhost:4999/home 上工作,但是在我输入姓名、电子邮件和电话号码后提交表单后,我我被重定向回 l​​ocalhost:4999/home,这就是我收到此错误的地方。它在线“cursor.execute(query, email)”

标签: python database flask web-applications


【解决方案1】:

您看到的错误是在对象已关闭后尝试使用它的结果。大多数使用with 关键字的对象都是为了控制对某些底层资源的访问。在这种情况下,它是数据库连接的游标。当您使用with 关键字时,Python 将在执行内部代码块之前执行特定方法,并在该代码块完成时执行特定方法。这允许代码使用with 关键字来控制诸如打开和关闭文件之类的事情。当您的代码退出with 块时,它会调用游标对象的close() 方法,从而终止与数据库的数据连接。在那之后,你继续使用光标对象,所以它会给你这个错误。

为了解决这个问题,每个涉及光标的交互都应该缩进到用with定义的代码块中。

见下文:

@app.route('/', methods=['GET', 'POST'])
@app.route('/home', methods=['GET', 'POST'])
def home():
    if request.form:
        name = request.form['name']
        email = request.form['email']
        phone_number = request.form['phone number']

        with conn.cursor() as cursor:
            query = 'SELECT * FROM LandingPage WHERE email = %s'
            cursor.execute(query, email)
            data = cursor.fetchone()
            conn.commit()
            error = None # new indentation starts at this line
            if data:
                error = "A person with this email already exists in the database"
                return render_template('home.html', error=error)
            else:
                ins = "INSERT INTO LandingPage (name, email, phone number) VALUES (%s, %s, %s)"
                cursor.execute(ins, (name, email, phone_number))

        conn.commit()
        # cursor.close() # this line is redundant
        return render_template('home.html')
    return render_template('home.html')

【讨论】:

  • 这是一个超级简洁明了的答案,我现在完全明白了。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-03
  • 2017-10-03
  • 2019-03-28
  • 2018-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多