python - Python 的 MySQLdb 的上下文管理器

标签 python mysql with-statement contextmanager

我已经习惯了(被宠坏了?)python 的 SQLite处理 SQL 数据库的接口(interface)。 python 的 SQLite API 中的一个不错的功能是“上下文管理器”,即 python 的 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 时自动为我运行它> 声明。它还可以很好地处理异常:如果在我提交任何内容之前发生异常,则数据库将回滚。

我现在使用的是 MySQLdb 接口(interface),它似乎不支持开箱即用的类似上下文管理器。我如何创建自己的?有一个相关问题here ,但它没有提供完整的解决方案。

最佳答案

Previously , MySQLdb 连接是上下文管理器。 截至this commit on 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 变量。

关于python - Python 的 MySQLdb 的上下文管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8067690/

相关文章:

python - 我怎样才能得到这个页面的内容?

python - Matplotlib xy 线图图例

php - 循环遍历数组,并将每次循环的结果作为变量插入到 MySQL

mysql - 使用 powershell 合并两个相似且两列不同的表

java - where查询区分大小写

python - python "with"命令可以用于选择性地写入文件

sql - 如何使用 Postgresql 在另一个 Select 中执行 Select

Python __enter__/__exit__ vs __init__(或 __new__)/__del__

python - mac 上的 ssh -X 在 matplotlib 中给出错误

python - 使用函数和 for 循环将文本与多个文件的列表进行比较