2011-08-07 5 views
2

私は、sqlite3がマルチプロセッシング環境の中でそれを使用するとき、本当に有効でも信頼できるものでもないことに気付きました。各プロセスは、複数のスレッドによって接続が使用されるように、同じデータベースにデータを書き込もうとします。私はcheck_same_thread = Falseオプションで試してみましたが、挿入の回数はかなりランダムです。関数の一部だけを並列処理し(Webからデータを取得する)、その出力をリストに積み重ねて、それらをまとめてテーブルに入れるか、sqliteで複数の接続を処理する信頼できる方法がありますか?SQLite3とマルチプロセッシング

答えて

0

sqlitedictのようなものを使用することができるかもしれません。

+1

ここでは、マルチスレッドのサポートは、SQLiteがProgrammingError例外をスローしないため、コードを破損しないことを意味します。しかし、lib doc - > "multithreaded supportはパフォーマンスのメリットはありません。" (https://pypi.python.org/pypi/sqlitedict) – miguelfg

6

まず、マルチプロセス(複数プロセス)とマルチスレッド(複数のスレッドの1つのプロセス内)に違いがあります。

ここでは、マルチスレッドについて話しているようです。マルチスレッド環境でSQLiteを使用する際に注意すべき注意点がいくつかあります。 SQLite documentationは、次のことを言及:

  • 以上 1つのスレッドで同時に同じデータベース接続を使用しないでください。
  • 一部のオペレーティングシステムでは、データベース接続は、最初に作成された同じスレッドで常に使用される必要があります( )。

詳細についてはこちらをご覧ください:Is SQLite thread-safe?

+2

とそれに追加するには、SQLiteはロックがタイムアウト(失敗)にいくつかの呼び出しを引き起こす可能性があることご承知する限り、マルチプロセス環境では正常に動作し、彼らはその後、再試行する必要があること。 –

+1

私はthread/process-differenceを知っています。私は複数のプロセス(プールを持つマルチプロセッシングモジュール)を使用しています。あなたがまたする必要が – dorvak

+0

...私は問題は、DB-ロックされていると思いますが、プロセスの内部で生成されたエラーなし - メッセージはありません(一般的には、私のプロセスはエラーに気をドント、彼らはちょうどそれらを渡すように見えます)複数のシステム間でプロセスを構築している場合は、ネットワーク化されたシステムでファイルロックを楽しむことができます。それは困難な領域です。 _really_より良いプロセスの数を1つのシステム上に持つために十分に小さく保つこと。 –

0

私はあなたがsqliteのを使用して、記述のようなシステムを構築する必要があった場合は、その後、私は非同期サーバを書き込むことによって開始する(asynchatを使用してモジュール)を使用してSQLiteデータベースアクセスをすべて処理し、そのサーバーを使用するために他のプロセスを記述します。 dbファイルに直接アクセスするプロセスが1つしかない場合は、2つのプロセスがそれぞれのつま先で足踏みする危険性がないように厳密な一連の照会を強制することができます。また、DBを連続的に開閉するよりも高速です。

実際、セッションを維持しないようにする、つまり、すべてのデータベーストランザクションが独立するように他のすべてのプロセスを記述しようとします。少なくともこれはトランザクションにSQLステートメントのリストを含むことを許可することを意味し、さらにif thenケーパビリティを必要とするかもしれないので、レコードをSELECTし、フィールドがXと等しいかどうかを確認してからUPDATEそのフィールド。トランザクションごとに既存のアプリがデータベースを閉じている場合は、セッションについて心配する必要はありません。辞書のようなインターフェースとマルチスレッドアクセスをサポートして、Pythonのsqlite3のデータベース周りの軽量ラッパー:

あなたはnosqlite http://code.google.com/p/nosqlite/

+0

私は2番目の部分を取得していません...私の現在の設定では、各プロセスがデータベースを接続し、INSERTを実行し、コミットして接続を閉じます。 – dorvak

2
私は実際には非常によく似た何かに取り組んできました

  • 各プロセスの労働者が取得含まれていくつかのものをし

    • 複数のプロセス(私のために4〜32の労働者の処理プール)情報 ウェブから(錬金術のためのAlchemy APIへの呼び出し)
    • 各プロセスはそれ自身のsqlite3接続をすべて1つのファイルに開き、各 プロセスはスタックから次のタスクを取得する前に1つのエントリを追加します

    私はあなたと同じ問題を抱えていると思っていましたが、Webから情報を取得する際に重複して矛盾する問題が発生したと考えました。私はそこにいたので、sqliteとマルチプロセッシングに関するいくつかの拷問テストを行い、すべてのプロセスワーカーを実行することができ、すべての接続と追加を調整なしで同じsqliteファイルに追加できました。

    これで、 "(ウェブからデータを取得しています)"というフレーズを見ています。おそらく、実際にsqlite3接続で問題が発生していることを確認するために、そのデータをダミーデータで置き換えることができます。少なくとも私のテストケース(別のウィンドウで今実行中)では、複数のプロセスがすべて問題なく問題なく独自の接続を追加できることがわかりましたが、2つのプロセスがお互いに進んでいるときに問題が発生していますWeb API(実際には非常に奇妙なエラー)のため、期待されるデータが得られないことがあります。もちろん、データベースに空きスロットが残っています。私の最終的な解決策は、各作業者の中でこの失敗を検出し、発生したときにWeb APIコールを再試行することでした(より洗練されている可能性がありますが、これは個人的なハックのためでした)。

    私の謝罪これはコードなしで、あなたのケースに適用されない場合、それはあなたが直面しているかを知るのは難しいですが、説明はあなたの配慮を広げる可能性がある場合、私は思ってしまいます。