之前,MySQLdb的连接是上下文管理器。
但是自2018-12-04这个提交以来,MySQLdb的连接不再是上下文管理器,
用户必须显式地调用conn.commit()或conn.rollback(),或编写自己的上下文管理器,例如下面的代码。
你可以像这样使用:
import config
import MySQLdb
import MySQLdb.cursors as mc
import _mysql_exceptions
import contextlib
DictCursor = mc.DictCursor
SSCursor = mc.SSCursor
SSDictCursor = mc.SSDictCursor
Cursor = mc.Cursor
@contextlib.contextmanager
def connection(cursorclass=Cursor,
host=config.HOST, user=config.USER,
passwd=config.PASS, dbname=config.MYDB,
driver=MySQLdb):
connection = driver.connect(
host=host, user=user, passwd=passwd, db=dbname,
cursorclass=cursorclass)
try:
yield connection
except Exception:
connection.rollback()
raise
else:
connection.commit()
finally:
connection.close()
@contextlib.contextmanager
def cursor(cursorclass=Cursor, host=config.HOST, user=config.USER,
passwd=config.PASS, dbname=config.MYDB):
with connection(cursorclass, host, user, passwd, dbname) as conn:
cursor = conn.cursor()
try:
yield cursor
finally:
cursor.close()
with cursor(SSDictCursor) as cur:
print(cur)
connection = cur.connection
print(connection)
sql = 'select * from table'
cur.execute(sql)
for row in cur:
print(row)
要使用它,您需要将
config.py
放置在 PYTHONPATH 中,并在那里定义 HOST、USER、PASS 和 MYDB 变量。
__exit__
函数假设self.connection
存在。如果在__enter__
函数中实例化连接并引发异常,则__exit__
函数将引发第二个异常,因为没有connection
可以调用rollback
或commit
。因此,不,这样做并不更安全。 - unutbu__enter__
中初始化连接。还请参阅此文档示例。 - unutbucontextlib.contextmanager
装饰器,而不是显式定义__enter__
和__exit__
,因为它使代码更短,更易读。 - unutbu