25

私はチュートリアルを行っていて、sqlite3 との接続を処理する方法に出くわしました。次に、WITH キーワードについて調べたところ、それが try,except,finally の方法の代わりになることがわかりました。

ファイル処理の場合、「WITH」は自動的にファイルのクローズを処理すると言われ、zetcodeチュートリアルで述べたように、接続と同様に考えました:-

「 with キーワードを使用すると、Python インタープリターはリソースを自動的に解放します。また、エラー処理も提供します。」http://zetcode.com/db/sqlitepythontutorial/

だから私は物事を処理するこの方法を使用するのが良いだろうと思ったが、私は両方の(内側のスコープと外側のスコープ)ステートメントが機能する理由を理解できなかった?WITH は接続を解放すべきではありませんか?

import sqlite3

con = sqlite3.connect('test.db')

with con:    
    cur = con.cursor()    

    cur.execute('SELECT 1,SQLITE_VERSION()')
    data = cur.fetchone()   
    print data        

cur.execute('SELECT 2,SQLITE_VERSION()')
data = cur.fetchone()
print data

出力する

(1, u'3.6.21')
(2, u'3.6.21')

ここでWITHが何をしているのか(または一般的に何をしているのか)はわかりません。そのため、このコンテキストでTRY CATCHよりもWITHを使用する方法について詳しく教えてください。

また、クエリごとに接続を開いたり閉じたりする必要がありますか? (引数を指定して毎回呼び出す関数内でクエリを作成しています)それは良い習慣でしょうか?

4

3 に答える 3

22

一般に、コンテキスト マネージャは、使用時に作成者が実行したいことを自由に実行できます。特定のシステム状態の設定/リセット、使用後のリソースのクリーンアップ、ロックの取得/解放など。

特に、Jon がすでに書いているように、データベース接続オブジェクトは、コンテキスト マネージャーとして使用されるとトランザクションを作成します。接続を自動的に閉じたい場合は、次のことができます

with contextlib.closing(sqlite3.connect('test.db')) as con:
    with con as cur:
        cur.execute('SELECT 1,SQLITE_VERSION()')
        data = cur.fetchone()   
        print data        

    with con as cur:
        cur.execute('SELECT 2,SQLITE_VERSION()')
        data = cur.fetchone()
        print data
于 2013-10-22T17:38:08.280 に答える
16

ドキュメントから: http://docs.python.org/2/library/sqlite3.html#using-the-connection-as-a-context-manager

接続オブジェクトは、トランザクションを自動的にコミットまたはロールバックするコンテキスト マネージャーとして使用できます。例外が発生した場合、トランザクションはロールバックされます。それ以外の場合、トランザクションはコミットされます。

したがって、コンテキストマネージャーは接続を解放しません。代わりに、例外が発生した場合は接続で発生するすべてのトランザクションがロールバックされるか、そうでない場合はコミットされます... DELETE、クエリなどに役立ちますUPDATEINSERT

于 2013-10-22T15:51:19.027 に答える
13

sqlite3 をサポートする独自のラッパーを作成することもできますwith

class SQLite():
    def __init__(self, file='sqlite.db'):
        self.file=file
    def __enter__(self):
        self.conn = sqlite3.connect(self.file)
        self.conn.row_factory = sqlite3.Row
        return self.conn.cursor()
    def __exit__(self, type, value, traceback):
        self.conn.commit()
        self.conn.close()

with SQLite('test.db') as cur:
    print(cur.execute('select sqlite_version();').fetchall()[0][0])

https://docs.python.org/2.5/whatsnew/pep-343.html#SECTION000910000000000000000

于 2018-06-01T14:19:57.507 に答える