2012-04-02 11 views
1

パフォーマンス上の理由から、アプリケーションは起動時に特定のSQLAlchemyモデルインスタンスをメモリにロードします。これらのインスタンスは、アプリケーションの寿命を通じて変化するとは予想されないため、これは合理的な解決策です。SQLAlchemyトランザクションを超えたオブジェクトのキャッシュ

ほとんどの場合、これはうまくいきましたが、DetachedInstanceError: Instance <ZZZ at 0x3a23510> is not bound to a Session; attribute refresh operation cannot proceedが表示され、進行中の問題を引き起こす孤立した発生を観察しました。これは、同様にキャッシュされたオブジェクト上で遅延ロードされた関係にアクセスしようとしたときに(期待どおり)受け取るのと同じエラーです。

エラーは、.id属性へのアクセスが原因であるように見えますが、これはアクセスにDBリフレッシュを必要としないと考えられます。本当に私に迷惑をかけるのは、この例外を一貫して再現できないということです。

私の質問は、この例外が発生する可能性があり、SQLAlchemyインスタンスをトランザクション以外の場所に格納するためにどのような技術が使用されているのでしょうか?

+0

オブジェクトをロードすると、オブジェクトにセッションが関連付けられます。セッションにobjをチェックすることができれば、それを取得して 'True'を返します。したがって、 '.id'にアクセスしようとすると、そのオブジェクトがそのセッションに存在するかどうかを確認してください。 – Nilesh

答えて

2

.idは、オブジェクトがキャッシュに置かれる前に期限切れになっていれば、失われます。セッションがコミットまたはロールバックされると、デフォルトではすべての属性が期限切れになり、次回アクセス時に更新されます。

.idは、オブジェクトがデータベースから削除されている可能性がありますか、または主キーが変更されている(どちらの条件でもObjectDeletedErrorが発生する)ためです。

解決方法は、期限切れになる前にオブジェクトをキャッシュし、セッションがすべて終了する前にセッションからオブジェクトを削除するか、またはexpire_on_commitを無効にすることです。

関連する問題