1

私はsqliteデータベースに接続するいくつかのコードに取り組んでいます。上記のコードをデバッグする過程で、データベースへの開いている接続がハングしているという問題が発生しています。これは、エラーによってcloseコマンドの実行が妨げられたためです。dbとcは関数内で定義されているため、コマンドラインからこれらのオブジェクトを見つけて閉じることができません。これらは孤立した接続などのようなものですが、いずれにせよ、インタラクティブコンソールを閉じて再度開くまで、データベースで他のことを行うことができません。外観は次のとおりです。

def something()
    db=sqlite3.connect('mydatabase')
    c=db.cursor()

    somecode
    lots of different things happening in here
    this may have errors
    thus stopping execution

    db.commit()
    c.close()
    db.close()

「finally」ブロックで最後のクローズ操作を使用してtry/exception句を試しましたが、デバッグ中に例外がインタラクティブ出力に戻されるのを防ぎ、「サイレント」に失敗します(おそらく私はそうではありません)その部分を正しくやっていますか?)これを行うためのより良い方法はありますか?

4

3 に答える 3

5

一般に、... asステートメントと一緒に使用することをお勧めします:

with sqlite.connect(...) as db:
    with db.cursor() as c:
        ...

withステートメントは、withステートメントが終了するか、例外が発生したときに、オブジェクトでclose()が呼び出されることを保証します。そして、リターンやイールドが内側から呼ばれる場合でも。

詳細はこちら: http ://docs.python.org/2/reference/compound_stmts.html#with

于 2013-03-21T15:25:42.747 に答える
3

Piotrが指摘しているように、withステートメントを使用すると、データベースへの接続が明示的に閉じられない場合でも、コードがはるかに効率的になります。これは、ここで同様の質問によって見つかりました。

withステートメントを使用すると、withステートメント内のコードブロックがエラーなしで実行された場合にcon.commit()メソッドが実行されます。または、例外が発生した場合はcon.rollback()メソッド。

http://docs.python.org/2/library/sqlite3.htmlからの例

import sqlite3

con = sqlite3.connect(":memory:")
con.execute("create table person (id integer primary key, firstname varchar unique)")

with con:
    con.execute("insert into person(firstname) values (?)", ("Joe",))

# If Successful, con.commit() is called automatically afterwards
# else con.rollback() is called after the with block finishes with an exception, 
# the exception is still raised and must be caught

try:
    with con:
        con.execute("insert into person(firstname) values (?)", ("Joe",))
except sqlite3.IntegrityError:
    print "couldn't add Joe twice"

データベース接続オブジェクトのメソッドであるショートカットメソッドcon.execute()の使用に注意してください。これにより、カーソルオブジェクトが暗黙的に作成され、結果が返されるため、記述する必要のあるコードがさらに少なくなります。

于 2013-07-03T10:30:49.457 に答える
0

リソースをクリーンアップするには、以下のみ finallyを使用します。

db = sqlite.connect(...)
try:
    ...
    c = db.cursor()
    try:
        ...
    finally:
        c.close()
    ...
finally:
    db.close()
于 2013-03-21T15:19:44.990 に答える