23

を使用するとキャッシュの問題が発生しますsqlalchemy

sqlalchemyMySQLデータベースにデータを挿入するために使用します。次に、別のアプリケーションでこのデータを処理し、直接更新します。

ただしsqlalchemy、更新されたデータではなく、常に古いデータを返します。リクエストがキャッシュされたと思いますsqlalchemy...だから...どうすれば無効にできますか?

4

6 に答える 6

49

トランザクションに対してローカルである通常の SQLAlchemy ID マップに加えて、「キャッシュ」が作用していると人々が考えている通常の原因は、トランザクションの分離の影響を観察していることです。session.commit()SQLAlchemy のセッションはデフォルトでトランザクション モードで動作します。つまり、データをデータベースに保持するために が呼び出されるまで待機します。この間、別の場所で進行中の他のトランザクションには、このデータは表示されません。

ただし、トランザクションは分離されているため、さらにひねりがあります。進行中の他のトランザクションは、トランザクションのデータがコミットされるまで表示されないだけでなく、場合によっては、コミットまたはロールバックされるまで表示されないこともあります (これは、 close() がここで持っているのと同じ効果です) . 平均的な分離度のトランザクションは、それまでにロードされた状態を保持し、実際のデータが変更された場合でも、トランザクションに対してローカルで同じ状態を提供し続けます。これは、トランザクション分離の用語で反復可能読み取りと呼ばれます。

http://en.wikipedia.org/wiki/Isolation_%28database_systems%29

于 2012-04-18T14:51:50.660 に答える
19

この問題は私にとって本当にイライラさせられましたが、ついにそれを理解しました.

古い PHP サイトと一緒に Flask/SQLAlchemy アプリケーションを実行しています。PHP サイトはデータベースに書き込みますが、SQLAlchemy は変更を認識しません。

sessionmaker の設定 autoflush=True を試してみましたが失敗しました クエリを実行する前に db_session.flush()、db_session.expire_all()、および db_session.commit() を試しましたが、どれも機能しませんでした。まだ古いデータが表示されました。

最後に、SQLAlchemy ドキュメントのこのセクションに出くわしました: http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html#transaction-isolation-level

isolation_level の設定はうまくいきました。これで、私の Flask アプリは PHP アプリと「通信」しています。コードは次のとおりです。

engine = create_engine(
    "postgresql+pg8000://scott:tiger@localhost/test",
    isolation_level="READ UNCOMMITTED"
)

SQLAlchemy エンジンが「READ UNCOMMITED」isolation_level で開始されると、「ダーティ リード」が実行されます。これは、データベースからコミットされていない変更を直接読み取ることを意味します。

お役に立てれば


これは、コメントのAaronDの厚意による可能な解決策です

from flask.ext.sqlalchemy import SQLAlchemy

class UnlockedAlchemy(SQLAlchemy):
    def apply_driver_hacks(self, app, info, options):
        if "isolation_level" not in options:
            options["isolation_level"] = "READ COMMITTED"
    return super(UnlockedAlchemy, self).apply_driver_hacks(app, info, options)
于 2013-08-14T07:11:55.633 に答える
4

さらにzzzeekの優れた回答に、

同様の問題がありました。短い生活セッションを使用して問題を解決しました。

with closing(new_session()) as sess:
    # do your stuff

タスク、タスク グループ、またはリクエストごとに新しいセッションを使用しました (Web アプリの場合)。これで「キャッシュ」の問題が解決しました。

この資料は私にとって非常に役に立ちました。

いつセッションを構築し、いつコミットし、いつ閉じるか

于 2013-04-03T12:59:56.407 に答える
0

まず、SQLAlchemyのキャッシュはありません。DBからデータをフェッチする方法に基づいて、データベースが他のユーザーによって更新された後にテストを実行して、新しいデータを取得できるかどうかを確認する必要があります。

(1) use connection:
connection = engine.connect()
result = connection.execute("select username from users")
for row in result:
    print "username:", row['username']
connection.close()
(2) use Engine ...
(3) use MegaData...

次の手順に従ってください:http://docs.sqlalchemy.org/en/latest/core/connections.html

もう1つの考えられる理由は、MySQLDBが永続的に更新されていないことです。MySQLサービスを再起動し、確認してください。

于 2012-04-18T14:03:20.523 に答える
-4

私が知っているように、SQLAlchemyはキャッシュを保存しないため、ログ出力を確認する必要があります。

于 2012-04-18T13:21:13.370 に答える