我正在尝试创建登录功能。但它只适用于那些。例如 - 当我提供错误的用户名和密码时,我得到了正确的错误按摩,“取消该消息并提供正确的用户名和密码后无法登录”,然后我得到“pymysql.err.Error:已经关闭”下面的示例代码
import pymysql
# Connect to the database
connection = pymysql.connect(host='localhost',
user='root',
password='',
db='python_code',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
class LoginModel:
def check_user(self, data):
try:
with connection.cursor() as cursor:
# Read a single record
sql = "SELECT `username` FROM `users` WHERE `username`=%s"
cursor.execute(sql, (data.username))
user = cursor.fetchone()
print(user)
if user:
if (user, data.password):
return user
else:
return False
else:
return False
finally:
connection.close()
答案 0 :(得分:2)
这是罪魁祸首代码:
finally:
connection.close()
根据文档: “在离开try语句之前总是执行finally子句,无论是否发生了异常” 来自:https://docs.python.org/2/tutorial/errors.html
你没有描述你希望看到的替代行为而不是这个,但我的回答解决了你问题的关键。
答案 1 :(得分:1)
您创建连接的次数(一次)与关闭连接的次数(每次登录尝试次数)不匹配。
一个解决方法是移动你的:
connection = pymysql.connect(host='localhost',
user='root',
password='',
db='python_code',
charset='utf8mb4',
cursorclass=pymysql.cursors.DictCursor)
进入def check__user()
。它会起作用,因为你在每次调用时创建并关闭连接(正如其他人指出的那样,finally
子句总是被执行。)
这不是一个好的设计,因为获取数据库连接往往相对昂贵。因此,首选保持连接创建方法的外部 ....这意味着您必须删除方法中的connection.close()
。
我认为你将connection.close()
与cursor.close()
混为一谈。你想做后者,而不是前者。在您的示例中,您不必显式关闭游标,因为这会自动与您的with connection.cursor() as cursor:
行一起发生。
将finally
更改为except
,或完全删除try
块。