python - flask - 何时关闭 mysql 连接?
问题描述
关闭与mysql的连接的正确方法是什么?在我关注的教程中,作者用第一种方式关闭了连接,但这似乎不对。因为它会在返回后尝试关闭。那么以下哪一项是正确的关闭方式?
第一种方式,作者这样做的方式:
@app.route("/dashboard")
@login_required
def dashboard():
cur = mysql.connection.cursor()
result = cur.execute("SELECT * FROM articles")
articles = cur.fetchall()
if result > 0:
return render_template("dashboard.html", articles = articles)
else:
msg = "No Articles Yet"
return render_template("dashboard.html", msg = msg)
cur.close() // wrong
我的建议,我认为正确的方式:
@app.route("/dashboard")
@login_required
def dashboard():
cur = mysql.connection.cursor()
result = cur.execute("SELECT * FROM articles")
articles = cur.fetchall()
cur.close() // correct
if result > 0:
return render_template("dashboard.html", articles = articles)
else:
msg = "No Articles Yet"
return render_template("dashboard.html", msg = msg)
解决方案
不关闭游标的一个原因可能是 cur.fetchall() 可能会返回一个迭代器,如果在游标关闭之前迭代器没有完全处理,这可能会导致麻烦。在 SQLAlchemy 中,情况似乎如此,因为 fetchall 似乎确实返回了一个迭代器(根据docs)。
所以你可以做得更好:
articles = list(cur.fetchall())
cur.close()
这将确保在您关闭游标之前迭代器已用尽。
只有在你处理非常大的数据库的情况下,你才能做得更好(为列表节省空间——但渲染结果很可能会非常大):
articles = cur.fetchall()
cur.close()
if result > 0:
value = render_template("dashboard.html", articles = articles)
cur.close()
return value
else:
cur.close()
msg = "No Articles Yet"
return render_template("dashboard.html", msg = msg)
回到你原来的问题:是的,原来的代码是完全错误的,因为当方法之前返回时,永远不会达到关闭。意图可能是我上面描述的,但这就是不对的。