作業中のプログラムで別の問題が発生しました。基本的に、私のプログラムは最大 4 つの入力ファイルを受け取り、それらを処理し、それらから収集した情報をコンピューターの SQLite3 データベースに保存します。これにより、入力ファイルを再度実行しなくても、いつでもデータを表示できるようになりました。このプログラムは、基本的に入力スクリプトをインポートする AUI Notebook であるメイン スクリプトと、パネルとして使用する出力スクリプトを使用します。
データベースにデータを追加するには、結果を出力画面に直接返さないため、スレッドを使用できます。ただし、メイン テーブルの内容全体を表示する必要がある場合、25,000 レコードが読み込まれることになります。これらがロードされている間、私の GUI はロックされ、ほとんど常に「プログラムが応答しません」と表示されます。
スレッド化/マルチプロセッシングを使用してデータベースから 25k レコードを取得し、それらを ObjectListView ウィジェットにロードして、このプロセス中に GUI を使用できるようにしたいと考えています。データベースにデータを追加するために使用される同様のスレッド クラスを使用しようとすると、何も返されません。何も得られないと言っても過言ではありません。
これが私の大きな質問です。グローバル変数を使用せずにクエリをスレッド化して結果を返す方法はありますか? 理解できる例で解決策を見つけることができませんでしたが、間違った検索用語を使用している可能性があります。
当面の問題に関連するコードのスニペットを次に示します。
これは、データが ObjectListView ウィジェットの準備ができていることを確認するために使用するものです。
class OlvMainDisplay(object):
def __init__(self, id, name, col01, col02, col03, col04, col05,
col06, col07, col08, col09, col10, col11,
col12, col13, col14, col15):
self.id = id
self.name = name
self.col01 = col01
self.col02 = col02
self.col03 = col03
self.col04 = col04
self.col05 = col05
self.col06 = col06
self.col07 = col07
self.col08 = col08
self.col09 = col09
self.col10 = col10
self.col11 = col11
self.col12 = col12
self.col13 = col13
self.col14 = col14
self.col15 = col15
データを取得している2つのテーブル:
class TableMeta(base):
__tablename__ = 'meta_extra'
id = Column(String(20), ForeignKey('main_data.id'), primary_key=True)
col06 = Column(String)
col08 = Column(String)
col02 = Column(String)
col03 = Column(String)
col04 = Column(String)
col09 = Column(String)
col10 = Column(String)
col11 = Column(String)
col12 = Column(String)
col13 = Column(String)
col14 = Column(String)
col15 = Column(String)
class TableMain(base):
__tablename__ = 'main_data'
id = Column(String(20), primary_key=True)
name = Column(String)
col01 = Column(String)
col05 = Column(String)
col07 = Column(String)
extra_data = relation(
TableMeta, uselist=False, backref=backref('main_data', order_by=id))
これら 2 つのテーブルから収集するために 2 つのクエリを使用します。1 つはすべてのレコードを取得し、もう 1 つは複数の辞書を取り、辞書の内容に基づいてフィルターを適用する関数定義の一部です。両方のクエリは、各ノートブック パネルによってインポートされるメインの「ワーカー」スクリプトの一部です。
フィルターを適用する関数は次のとおりです。
def multiFilter(theFilters, table, anOutput, qType):
session = Session()
anOutput = session.query(table)
try:
for x in theFilters:
for attr, value in x.items():
anOutput = anOutput.filter(getattr(table, attr).in_(value))
except AttributeError:
for attr, value in theFilters.items():
anOutput = anOutput.filter(getattr(table, attr).in_(value))
anOutput = convertResults(anOutput.all())
return anOutput
session.close()
theFilters は、単一の辞書または辞書のリストのいずれかにすることができるため、"Try:" ステートメントが使用されます。関数がフィルタを適用すると、返された結果を別の関数で実行します。この関数は、OlvMainDisplay クラスから返された各結果を配置し、それらをリストに追加して OLV ウィジェットに渡します。
ここでも大きな問題ですが、グローバル変数を使用せずにクエリ (または複数のクエリ) をスレッド化し、結果を返す方法はありますか? または、一度に約 200 レコードを取得して、データを「チャンク単位で」OLV ウィジェットに追加することはできますか?
前もって感謝します。
-マイクS
--UPDATE-- 「Python でスレッドから戻り値を取得する方法」
を確認しましたが、受け入れられた回答は何も返さないか、GUI をロックしたままです (差異の原因がわからない)。作成するスレッドの数は最大で 5 つ程度に制限したいと考えています。
--New Update-- フィルター機能を一部修正しました。