14

セッションからクラスのインスタンスをデタッチしたいのですが、(クエリを発行せずに) 読み取り可能である必要があります。私は何日も前からドキュメントに目を通してきましたが、私が試みるすべてのアプローチがメッセージにつながります

DetachedInstanceError: Instance <MyModel at 0x36bb190> is not bound to a Session;
attribute refresh operation cannot proceed

私はzope.sqlalchemyPyramid のトランザクション マネージャーを使用しています。トランザクションがコミットされた、オブジェクトを使用できるようにしたい。「キャッシュされた」値、つまりトランザクションがコミットされる前に含まれていた値を読み取るためだけに必要です。

私が見つけた唯一の可能な解決策は、クラス(または属性自体)をラップしてから、変更を手動で追跡することでした(それを行うことはできますが、それは本当に醜く、まったくPythonicではありません)。

SQLAlchemy がこれらの値を更新しようとするのを防ぐ方法はありますか?

Noneフォールバックとして、トランザクションがコミットされた後に上記のエラーがスローされない限り、単に を返すことさえできます。

4

4 に答える 4

11

http://docs.sqlalchemy.org/en/latest/orm/session_api.html

探していると思いますexpire_on_commit = False

これにより、オブジェクトを切り離して引き続き使用できると思います。ただし、それを変更してコミットしようとすると、DetachedInstanceError.

于 2013-04-20T01:33:59.517 に答える
4

これを試して:

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension(), expire_on_commit=False))

私もこの問題を抱えていて、使用すると問題がexpire_on_commit=False解決しました。

于 2015-01-11T17:18:07.103 に答える
3
@contextmanager
def make_session_scope(Session):
    """Provide a transactional scope around a series of operations."""
    session = Session()
    session.expire_on_commit = False
    try:
        yield session
        session.commit()
    except:
        session.rollback()
        raise
    finally:
        session.close()

 with make_session_scope(session) as session:
      query = session.query(model)
于 2015-12-08T03:06:19.087 に答える