0

昨日まで、アプリケーションに SQLite を使用していました。今日、MySQL を使用して切り替えるのに十分な理由 (アプリケーションの複数のインスタンス) を見つけましたpymysql

ある時点で、私のアプリケーションはデータベースに 300 行のクエリを実行します。

cur.execute('select ime,brPredmeta,statusStr,sudskiBr ,sudija ,datumRasprave,statusPredmeta, zaduzen,datumZaduzenja from predmeti')
sviaktivni = cur.fetchall()
sviaktivni = list(sviaktivni) #make a list of tuples
sviaktivni.sort(key=operator.itemgetter(0)) #sort the list

その後、変数を抽出し、それらの変数を使用して HTML ドキュメントを作成し、それをプリンター (PDF または通常のプリンター) に送信します。HTML を生成するコードは非常に単純です。「ヘッダー」用の数行のテーブル (わかりやすくするためにここでは省略) と、次のようなコードを含む「本文」用の別のテーブル:

#extract the variables
for tuple in sviaktivni:
    ime,brPredmeta,statusStr,sudskiBr ,sudija ,datumRasprave,statusPredmeta, zaduzen,datumZaduzenja = tuple
#done extracting

  body = ('<html><head><title></title>'
    '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>'
    '<style></style>'
    '</head>'
    '<body>'
    '<table align ="center" border="0" width="100%" style="table-layout:fixed">'
    '<tr height="10%">'
    '<td align="left" width="20">'+str(brojac)+'.</td>'
    '<td align="left" width="180">'+ime+'</td>'
    '<td align="left" width="100">'+str(brPredmeta)+'</td>'
    '<td align="left" width="80">'+statusStr+'</td>'
    '<td align="left" width="80">'+str(sudskiBr)+'</td>'
    '<td align="left" width="140">'+sudija+'</td>'
    '<td align="left" width="150">'+zaduzen+'</td>'
    '<td align="left">'+datumZaduzenja+'</td>'
    '<td align="right"> '+statusPredmeta+' </td>'
    '</tr>'
    '</table>'
    '</body>'
    '</html>')

  self.ui.printHTML.append(body)

私の問題は、クエリが即座に実行されることですが、その後 CPU が 100% でスタックし、プログラム全体がフリーズすることです。印刷プレビュー ダイアログにデータが表示される場合や、空のウィンドウが表示される場合があります。いずれにせよ、アプリ全体がフリーズしています。

SQLite を使用した同じコードで問題はありませんでした。私は何をすべきか?sqlite に戻って、データベースが破損する危険がありますか?

4

2 に答える 2

1

SQLの結果全体をメモリにロードするだけでなく、すべての場合にこれが機能することを期待してください。さらに、データベースを使用して並べ替えを行うのが得意です。

カーソルをループして結果を1つずつ処理するだけで、中間結果でメモリをいっぱいにする必要がなくなります。

cur.execute('''
    select 
        ime, brPredmeta, statusStr, sudskiBr, sudija,
        datumRasprave,statusPredmeta, zaduzen,datumZaduzenja
    from predmeti
    order by ime
    ''')
for row in cur:
    ime, brPredmeta, statusStr, sudskiBr, sudija, datumRasprave, statusPredmeta, zaduzen, datumZaduzenja = row
    # Process row data.
于 2012-09-04T12:29:35.940 に答える
0

SQLiteドキュメントから取得...

複数のアプリケーションまたは同じアプリケーションの複数のインスタンスが、1 つのデータベース ファイルに同時にアクセスできますか?

複数のプロセスが同時に同じデータベースを開くことができます。複数のプロセスが同時に SELECT を実行できます。ただし、いつでもデータベースに変更を加えることができるプロセスは 1 つだけです。

SQLite は、リーダー/ライター ロックを使用してデータベースへのアクセスを制御します。(リーダー/ライター ロックをサポートしていない Win95/98/ME では、代わりに確率的シミュレーションが使用されます。) ただし、データベース ファイルが NFS ファイルシステムに保持されている場合、このロック メカニズムが正しく機能しない可能性があることに注意してください。これは、多くの NFS 実装で fcntl() ファイルのロックが壊れているためです。複数のプロセスが同時にファイルにアクセスしようとする可能性がある場合は、SQLite データベース ファイルを NFS に置くことは避けてください。Windows では、Microsoft のドキュメントによると、Share.exe デーモンを実行していない場合、FAT ファイルシステムではロックが機能しない可能性があります。Windows の経験が豊富な人は、ネットワーク ファイルのファイル ロックは非常にバグが多く、信頼できないと言っています。彼らの言うことが本当なら、

SQLite ほど多くの同時実行性をサポートする組み込み SQL データベース エンジンは他にありません。SQLite では、複数のプロセスでデータベース ファイルを一度に開いたり、複数のプロセスでデータベースを一度に読み取ったりすることができます。プロセスが書き込みを行う場合、更新中はデータベース ファイル全体をロックする必要があります。しかし、通常は数ミリ秒しかかかりません。他のプロセスは、ライターが完了するのを待ってから、処理を続行します。通常、他の組み込み SQL データベース エンジンでは、一度にデータベースに接続できるプロセスは 1 つだけです。

ただし、クライアント/サーバー データベース エンジン (PostgreSQL、MySQL、Oracle など) は通常、より高いレベルの同時実行をサポートし、複数のプロセスが同じデータベースに同時に書き込むことを許可します。アクセスを調整するための適切に制御された単一のサーバー プロセスが常に存在するため、クライアント/サーバー データベースではこれが可能です。アプリケーションで多くの同時実行が必要な場合は、クライアント/サーバー データベースの使用を検討する必要があります。しかし、経験上、ほとんどのアプリケーションは、設計者が想像するよりもはるかに少ない並行性を必要とすることが示唆されています。

SQLite が別のプロセスによってロックされているファイルにアクセスしようとすると、デフォルトの動作は SQLITE_BUSY を返すことです。sqlite3_busy_handler() または sqlite3_busy_timeout() API 関数を使用して、C コードからこの動作を調整できます。

于 2012-09-04T09:47:15.540 に答える