我习惯(宠坏了?)python的SQLite接口来处理SQL数据库。python的SQLite API中的一个不错的功能是“上下文管理器”,即python的with语句。我通常以以下方式执行查询:
with
import as sqlite with sqlite.connect(db_filename) as conn: query = "INSERT OR IGNORE INTO shapes VALUES (?,?);" results = conn.execute(query, ("ID1","triangle"))
使用上面的代码,如果我的查询修改了数据库并且忘记了运行conn.commit(),则上下文管理器在退出with语句后自动为我运行它。它还可以很好地处理异常:如果在我提交任何内容之前发生异常,则数据库将回滚。
conn.commit()
我现在正在使用该MySQLdb接口,该接口似乎不支持开箱即用的类似上下文管理器。我如何创建自己的?还有一个相关的问题在这里,但它并没有提供一个完整的解决方案。
MySQLdb
以前,MySQLdb连接是上下文管理器。从2018 年12月4日提交该内容开始,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变量。
config.py