2016-05-06 42 views
1

ここに私の最初の投稿があります。以前は単一のスレッドデータベースアプリケーション(postgresql、python2.7、sqlalchemy)をマルチスレッド化しようとしています。Sqlalchemy scoped_sessionと "already attached"エラー

私はオンラインの指示に従い、セッションハンドラを次のように変更しました。これは、作業者を起動する前に制御スレッドで行われます。

config.engine = create_engine("postgresql://foo:[email protected]/foo", echo=False) 
config.session_factory = sessionmaker(bind=config.engine) 
config.Session = scoped_session(config.session_factory) 

これは私が追加のスレッドから受け取るエラーメッセージです。スレッドが起動すると、それはスコープのセッションの新しいインスタンスを作成し、それはそのセッションのコンテキストに制御スレッドから受信したオブジェクト(self.channel)を追加しようとします:

self.session = config.Session() 
self.session.add(self.channel) 

私は労働者から取得エラースレッドはこれです:

InvalidRequestError: Object '<YChannel at 0x7ff3bab09490>' is already attached to session '1' (this is '3') 

私は間違っていますか?セッションがスコープされたセッションではなかったときのエラーですが、スコープされたセッションに切り替えるとすぐに消えてしまうことがドキュメントから分かりました。

リチャード

+0

違いは、異なるセッションを持つスレッド間でオブジェクトを共有しているということです。これを可能にしたい場合は、古いセッションからインスタンスを切り離し、新しいセッションに再接続する必要があります。 – univerio

+0

それではどうすれば解決できますか?私は別のスレッドで監視したり操作したりする必要のあるテーブルを持っています。異なるスレッドが同じオブジェクトを変更しないようにするための組み込みのメカニズムがありますが、すべてのスレッドのストレージは同じテーブルセットにあります。 –

+0

インスタンスを別のスレッドに送信する前にセッションからデタッチし、受信スレッドでインスタンスを再接続する必要があります。 – univerio

答えて

0

コメントでウニヴェルソで言ったように、あなたは、複数のセッション/スレッド間でオブジェクトを共有しようとしています。 チャネルオブジェクトがメインスレッドで作成されます。エグゼキュータを起動すると、スレッド1が新しいセッションを作成し、チャネルオブジェクトをそのセッションに追加します。今すぐスレッド2が実行されると、独自のセッションが作成され、チャネルのオブジェクトがセッションに再び追加されます。オブジェクトはセッション間で共有できないため、例外があります。

これを解決するには、実際に達成したいことに依存します。 チャネルのオブジェクトが1つしかない場合は、なぜ複数のスレッドとセッションを使用しますか。複数のチャネルオブジェクトがある場合、スレッド自体にオブジェクトを作成することを検討できます。

関連する問題