web-dev-qa-db-ja.com

Pythonデータベース接続閉じる

以下のコードを使用すると、接続が開いたままになります。どうすれば閉じられますか?

import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest') 

csr = conn.cursor()  
csr.close()
del csr
44
Merlin

接続には、PEP-249(Python Database API Specification v2.0)で指定されている close メソッドがあります。

import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest') 

csr = conn.cursor()  
csr.close()
conn.close()     #<--- Close the connection

pyodbcconnectioncursor は両方ともコンテキストマネージャであるため、現在では次のように記述する方が便利です(望ましい)。

import pyodbc
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest') 
with conn:
    crs = conn.cursor()
    do_stuff
    # conn.commit() will automatically be called when Python leaves the outer `with` statement
    # Neither crs.close() nor conn.close() will be called upon leaving the the `with` statement!! 

Conn.close()が呼び出されない理由の説明については、 https://github.com/mkleehammer/pyodbc/issues/4 を参照してください。

元のコードとは異なり、これによりconn.commit()が呼び出されることに注意してください。 withをいつ呼び出すかを制御するには、外側のcommitステートメントを使用します。


また、 ドキュメント ごとにwithステートメントを使用するかどうかに関係なく、

接続は削除されると自動的に閉じられます(通常、範囲外になると)。通常[conn.close()]を呼び出す必要はありませんが、必要に応じて明示的に接続を閉じることができます。

同様に カーソル用 (私の強調):

カーソルは、削除されると自動的に閉じられます(通常、範囲外になると)。したがって、[csr.close()]を呼び出す必要は通常ありません

52
unutbu

次のように、接続全体をコンテキストマネージャーでラップできます。

_from contextlib import contextmanager
import pyodbc
import sys

@contextmanager
def open_db_connection(connection_string, commit=False):
    connection = pyodbc.connect(connection_string)
    cursor = connection.cursor()
    try:
        yield cursor
    except pyodbc.DatabaseError as err:
        error, = err.args
        sys.stderr.write(error.message)
        cursor.execute("ROLLBACK")
        raise err
    else:
        if commit:
            cursor.execute("COMMIT")
        else:
            cursor.execute("ROLLBACK")
    finally:
        connection.close()
_

次に、データベース接続が必要な場所で次のようなことを行います。

_with open_db_connection("...") as cursor:
    # Your code here
_

Withブロックを離れると、接続が閉じます。これは、例外が発生した場合、またはwith open_db_connection("...", commit=True)を使用してブロックを開かなかった場合にもトランザクションをロールバックします。

50
AndrewF

デフォルトで有効になっているプーリングをオフにしてみてください。詳細については、 this の説明を参照してください。

import pyodbc
pyodbc.pooling = False
conn = pyodbc.connect('DRIVER=MySQL ODBC 5.1 driver;SERVER=localhost;DATABASE=spt;UID=who;PWD=testest') 

csr = conn.cursor()  
csr.close()
del csr
6
Matthew Rankin

Pyodbcのドキュメントによると、SQLサーバーへの接続 デフォルトでは閉じられません サーバーへのラウンドトリップを保存するためにclose()が呼び出されると、一部のデータベースドライバーは接続を閉じません。

close()を呼び出すときに接続を閉じるには、プーリングをFalseに設定する必要があります。

import pyodbc

pyodbc.pooling = False
3
hamzed