Python 我可以将pymysql.connect()与“连接”一起使用吗;加上;陈述

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

以下是pymysql中的示例:

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