Python 我可以将pymysql.connect()与“连接”一起使用吗;加上;陈述
以下是pymysql中的示例:Python 我可以将pymysql.connect()与“连接”一起使用吗;加上;陈述,python,with-statement,pymysql,Python,With Statement,Pymysql,以下是pymysql中的示例: conn = pymysql.connect(...) with conn.cursor() as cursor: cursor.execute(...) ... conn.close() 我可以改为使用以下选项,还是会留下一个长期的连接? (执行成功) (Python3,最新的pymysql)这看起来不安全,如果您仔细看,\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
conn = pymysql.connect(...)
with conn.cursor() as cursor:
cursor.execute(...)
...
conn.close()
我可以改为使用以下选项,还是会留下一个长期的连接?
(执行成功)
(Python3,最新的pymysql)这看起来不安全,如果您仔细看,
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。对于pymysql连接,它们如下所示:
def __enter__(self):
"""Context manager that returns a Cursor"""
return self.cursor()
def __exit__(self, exc, value, traceback):
"""On successful exit, commit. On exception, rollback"""
if exc:
self.rollback()
else:
self.commit()
def __enter__(self):
return self
def __exit__(self, *exc_info):
del exc_info
self.close()
from contextlib import contextmanager
import pymysql
@contextmanager
def get_connection(*args, **kwargs):
connection = pymysql.connect(*args, **kwargs)
try:
yield connection
finally:
connection.close()
with get_connection(...) as con:
with con.cursor() as cursor:
cursor.execute(...)
因此,退出条款似乎并没有关闭连接,这意味着它将继续存在。我不知道他们为什么这样做。不过,你可以自己制作这样的包装
您可以通过创建多个游标来回收连接。游标方法如下所示:
def __enter__(self):
"""Context manager that returns a Cursor"""
return self.cursor()
def __exit__(self, exc, value, traceback):
"""On successful exit, commit. On exception, rollback"""
if exc:
self.rollback()
else:
self.commit()
def __enter__(self):
return self
def __exit__(self, *exc_info):
del exc_info
self.close()
from contextlib import contextmanager
import pymysql
@contextmanager
def get_connection(*args, **kwargs):
connection = pymysql.connect(*args, **kwargs)
try:
yield connection
finally:
connection.close()
with get_connection(...) as con:
with con.cursor() as cursor:
cursor.execute(...)
所以他们确实关闭了自己。您可以在with
子句中创建一个连接并将其与多个游标一起重用
如果要在with
子句(例如上下文管理器)后面隐藏关闭连接的逻辑,一种简单的方法如下:
def __enter__(self):
"""Context manager that returns a Cursor"""
return self.cursor()
def __exit__(self, exc, value, traceback):
"""On successful exit, commit. On exception, rollback"""
if exc:
self.rollback()
else:
self.commit()
def __enter__(self):
return self
def __exit__(self, *exc_info):
del exc_info
self.close()
from contextlib import contextmanager
import pymysql
@contextmanager
def get_connection(*args, **kwargs):
connection = pymysql.connect(*args, **kwargs)
try:
yield connection
finally:
connection.close()
with get_connection(...) as con:
with con.cursor() as cursor:
cursor.execute(...)
然后,您可以像这样使用该上下文管理器:
def __enter__(self):
"""Context manager that returns a Cursor"""
return self.cursor()
def __exit__(self, exc, value, traceback):
"""On successful exit, commit. On exception, rollback"""
if exc:
self.rollback()
else:
self.commit()
def __enter__(self):
return self
def __exit__(self, *exc_info):
del exc_info
self.close()
from contextlib import contextmanager
import pymysql
@contextmanager
def get_connection(*args, **kwargs):
connection = pymysql.connect(*args, **kwargs)
try:
yield connection
finally:
connection.close()
with get_connection(...) as con:
with con.cursor() as cursor:
cursor.execute(...)
正如前面所指出的,游标会自行处理,但是连接对上下文管理器的所有支持在几天前就被完全删除了,因此现在唯一的选择是编写您的:
作为替代方案,因为我想支持连接的上下文管理器模式,所以我用猴子补丁实现了它。这不是最好的方法,但它确实是一种东西
导入pymysql
MONKEYPATCH\u PYMYSQL\u CONNECTION=True
def monkeypatch_pymysql_connection():
Connection=pymysql.connections.Connection
def输入_补丁(自我):
回归自我
def exit_修补程序(自身、exc、值、回溯):
尝试:
self.rollback()#根据PEP-249关闭连接时隐式回滚
最后:
self.close()
连接。\输入\输入\补丁
连接。\uuuu退出\uuuu=退出\u补丁
如果MONKEYPATCH_PYMYSQL_连接:
monkeypatch_pymysql_连接()
MONKEYPATCH_PYMYSQL_CONNECTION=False#防止多次修补
这种方法适用于我的用例。我更喜欢在连接
类中使用\uuuuuuu进入
和\uuuu退出
方法。然而,当开发者在2018年末解决这个问题时,他们拒绝了这种方法。为什么不试试呢?正如我所说,它成功地执行了。但是,如果某件事可以完成,并不一定意味着应该完成:)我正在尝试确定是否应该这样做,否则会留下一个持久的连接。您是否建议在finally
子句中使用con.commit()?给定eg