0

何度も渡されるセッション オブジェクトがあり、ある時点で次のコード行が呼び出されます (これは避けられません)。

import transaction
transaction.commit()

これにより、セッションが使用できなくなります(閉じることにより)。

私の質問は2つの部分です:

  1. セッションがまだ有効かどうかを確認するにはどうすればよいですか?
  2. 死んだセッションを復活させる簡単な方法はありますか?

2 の場合: 私が現在知っている唯一の方法は、sqlalchemy.orm.scoped_session を使用してから、query(...)get(id) を何度も呼び出して、必要なモデル インスタンスを再作成することですが、これは非常に効率が悪いようです。

編集

エラーの原因となる一連のイベントの例を次に示します。

modelInstance = DBSession.query(ModelClass).first()
import transaction
transaction.commit()
modelInstance.some_relationship

そして、ここにエラーがあります:

sqlalchemy.orm.exc.DetachedInstanceError: Parent instance <CategoryNode at 0x7fdc4c4b3110> is not bound to a Session; lazy load operation of attribute 'children' cannot proceed

遅延読み込みをオフにしたくありません。

編集

DBSession.is_active は、この場合、セッションが実際に有効であるかどうかを示すものではないようです。

transaction.commit()
print(DBSession.is_active)

これはTrueを出力します...

編集 これはコメントするには大きすぎるように思えたので、ここに入れます。

zzzeek 氏は次のように述べています。

では、これが起こるようにコミットするにはどうすればよいでしょうか? transaction.commit の呼び出しが間違っています。正しい方法は何ですか?

4

1 に答える 1

1

ここで最初に観察することは、「トランザクションのインポート」がzope.transactionというパッケージであることです。これは、zope.sqlalchemy 拡張機能を介して、SQLAlchemy セッションがその 1 つである任意の数のサブタスクを保持する汎用トランザクションです。

ここで zope.sqlalchemy が行おうとしているのは、「トランザクション」の独自の管理に応答して、セッション自体の begin()/rollback()/commit() メソッドを呼び出すことです。

Session 自体は、内部トランザクションがコミットされていても、ほぼ常に使用できるように機能します。これが発生すると、次の使用時にセッションが続行され、autocommit=False の場合は新しいトランザクションが開始され、autocommit=True の場合は「autocommit」モードで続行されます。基本的に自動復活です。

セッションが続行できないのは、フラッシュが失敗し、rollback() メソッドが呼び出されていない場合です。これは、autocommit=False モードの場合、flush() 時にセッションが明示的に実行することを要求します。失敗します。セッションがこの特定の状態にあるかどうかを確認するために、session.is_active プロパティはその場合 False を返します。

zope.transaction が使用されているときにセッションを使用し続けることの意味を 100% 確信しているわけではありません。より大きなスキームで zope.transaction をどのように使用しているかに依存すると思います。

これは、これらの質問の多くが行うところ、つまりあなたが本当にやろうとしていることです。同様に、「必要なモデル インスタンスを再作成する」ことは、有効期限が切れた (中身が空になった)既存のインスタンスを参照していない限り、Session が行うことではありません。期限切れのオブジェクトは、何かにアクセスするとすぐに、セッションを介してデータベースから新しい状態を自動的にロードするため、ここで何かを行うようにセッションに指示する必要はありません。

もちろん、自動期限切れを完全にオフにするオプションもありますが、ここで問題に到達しているということは、何かが正常に機能していないことを意味します。あなたが得ているいくつかのエラーメッセージがあるように。あなたが抱えている問題が何であるかを正確に理解するには、より詳細な情報が必要です。

于 2012-10-04T15:02:53.537 に答える