pymysql.err.Error: Already closed
pymysql.err.Error: Already closed
我正在尝试创建一个登录功能。但它只适用于那些。例如,当我输入错误的用户 ID 和密码时,我得到了正确的错误提示 "Could't login" 在取消该消息并提供正确的用户 ID 和密码后,我得到 "pymysql.err.Error: Already closed" 以下是示例代码。
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()
这是罪魁祸首代码:
finally:
connection.close()
根据文档:
"A finally clause is always executed before leaving the try statement, whether an exception has occurred or not"
来自:https://docs.python.org/2/tutorial/errors.html
你没有描述你希望看到的替代行为而不是这个,但我的回答解决了你问题的症结所在。
您创建连接的次数(一次)和关闭连接的次数(每次登录尝试一次)不匹配。
一个解决方法是移动您的:
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
块。
有同样的问题。带有 psycopg2 驱动程序的 Postgres 需要“Finally 子句,如果与上下文管理器(with 子句)一起使用,它会关闭游标而不是连接。这同样不适用于 Pymysql。
我正在尝试创建一个登录功能。但它只适用于那些。例如,当我输入错误的用户 ID 和密码时,我得到了正确的错误提示 "Could't login" 在取消该消息并提供正确的用户 ID 和密码后,我得到 "pymysql.err.Error: Already closed" 以下是示例代码。
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()
这是罪魁祸首代码:
finally:
connection.close()
根据文档: "A finally clause is always executed before leaving the try statement, whether an exception has occurred or not" 来自:https://docs.python.org/2/tutorial/errors.html
你没有描述你希望看到的替代行为而不是这个,但我的回答解决了你问题的症结所在。
您创建连接的次数(一次)和关闭连接的次数(每次登录尝试一次)不匹配。
一个解决方法是移动您的:
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
块。
有同样的问题。带有 psycopg2 驱动程序的 Postgres 需要“Finally 子句,如果与上下文管理器(with 子句)一起使用,它会关闭游标而不是连接。这同样不适用于 Pymysql。