18

私はSQLデータベースを処理するためのPythonのSQLiteインターフェースに慣れています(甘やかされていますか?)。PythonのSQLiteのAPIの優れた機能の1つである「コンテキストマネージャー」、つまり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インターフェースを使用していますが、これは、そのままでは同様のコンテキストマネージャーをサポートしていないようです。自分で作成するにはどうすればよいですか?ここに関連する質問がありますが、完全な解決策を提供するものではありません。

4

2 に答える 2

27

以前は、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変数を定義します。

于 2011-11-10T02:34:49.420 に答える
19

この質問が最初に尋ねられてから状況が変わったと思います。やや紛らわしいことに(少なくとも私の観点からは)、最近のバージョンではMySQLdb、コンテキストで接続を使用すると(例のように)カーソルが表示されoursql、(ファイルを開いた場合のように)自動的に閉じるものではありません例えば)。

これが私がすることです:

from contextlib import closing
with closing(getConnection()) as conn: #ensure that the connection is closed
    with conn as cursor:               #cursor will now auto-commit
        cursor.execute('SELECT * FROM tablename')
于 2014-04-03T14:20:09.437 に答える