[解決済み] SQLAlchemy: セッションの作成と再利用
質問
ちょっとした質問です。SQLAlchemy
について話しています。
呼び出し
sessionmaker()
を一度呼び出すが、その結果生じる
Session()
クラスを呼び出します。私の場合、これは最初の
session.add(x)
などと書くと、まず
from project import Session
session = Session()
いままでやっていたのは、呼び出しが
session = Session()
をモデル内で
一度
を作成し、アプリケーションのどこにいても常に同じセッションをインポートします。これはWebアプリケーションなので、このようになります。
通常
という意味です。
しかし、どこに違いがあるのでしょうか?自分の関数が終了するまでデータベースのためにセッションを使用し、次にDBと話をしたいときに新しいセッションを作成することに対して、常に1つのセッションを使用することの不利な点は何でしょうか?
複数のスレッドを使用する場合、それぞれが独自のセッションを取得する必要があることは理解しました。しかし
scoped_session()
を使うことで、その問題が存在しないことをすでに確認していますよね?
私の仮定に間違いがあれば、明らかにしてください。
どのように解決するのですか?
sessionmaker()
はファクトリで、これは新しい
Session
オブジェクトを作成するための設定オプションを一か所にまとめることを推奨しています。 これはオプションです。
Session(bind=engine, expire_on_commit=False)
をいつでも呼び出すことができます。
Session
が必要な場合、その冗長性と冗長性を除いては、私は、それぞれが新しい、より混乱させる方法でこの冗長性の問題にアプローチする小規模な "ヘルパー"の増殖を止めたいと思いました。
そこで
sessionmaker()
を作成するためのツールに過ぎません。
Session
オブジェクトを作成するためのツールに過ぎません。
次の部分です。 問題は、新しい
Session()
を作るのと、ずっと1つだけ使うのとでは何が違うのかということです。 答え、あまりありません。
Session
は、あなたがそこに入れたすべてのオブジェクトのためのコンテナであり、そしてそれはまた、開いているトランザクションを追跡します。 を呼び出した瞬間に
rollback()
または
commit()
であれば、トランザクションは終了し
Session
は再びSQLを発行するように要求されるまで、データベースへの接続を持ちません。 マップされたオブジェクトへのリンクは弱い参照で、オブジェクトが保留中の変更から解放されていれば、その点でも
Session
は、アプリケーションがマップされたオブジェクトへの参照をすべて失うと、それ自体が空になって、まったく新しい状態に戻ってしまいます。 これをデフォルトの
"expire_on_commit"
の設定のままにしておくと、コミット後にすべてのオブジェクトが失効してしまいます。 もし、その
Session
が 5 分から 20 分間放置され、次に使用するときにデータベース内のあらゆるものが変更されていた場合、それらのオブジェクトが 20 分間メモリ内に置かれていたとしても、次にアクセスするときにはすべての新しい状態がロードされます。
ウェブアプリケーションでは、通常、なぜ新しい
Session
を作ったらどうでしょうか? この方法は、新しいリクエストがクリーンな状態で開始されることを保証します。 前のリクエストのオブジェクトがまだガベージコレクションされていない場合、そしてもしかしたら
"expire_on_commit"
をオフにした場合、前のリクエストからいくつかの状態がまだぶら下がっていて、その状態はかなり古いものである可能性さえあります。 もしあなたが注意深く
expire_on_commit
をオンにしたままにしておき、間違いなく
commit()
または
rollback()
で始まる場合は問題ないのですが、全く新しい
Session
で始めるなら、クリーンな状態で始めていることに疑問の余地はないでしょう。 そこで、各リクエストを新しい
Session
を使うのは、本当に一番簡単な方法です。
expire_on_commit
を呼び出す操作のために多くの余分な SQL が発生する可能性があるため、このフラグはほとんどオプションです。
commit()
を呼び出すような操作では、余分な SQL が発生する可能性があるからです。 これが質問の答えになるかどうかは分かりませんが。
次のラウンドは、スレッドについて言及されているものです。 アプリがマルチスレッド化されている場合は、必ず
Session
使用中がローカルで...何か。
scoped_session()
はデフォルトで現在のスレッドにローカルになります。 Web アプリでは、リクエストに対してローカルであることは、実際にはもっと良いことです。 Flask-SQLAlchemy は実際にカスタム "スコープ関数" を
scoped_session()
に送るので、リクエストスコープのセッションを得ることができます。 平均的なPyramidアプリケーションは、Sessionを"request"レジストリに貼り付けます。 これらのようなスキームを使用する場合、"create new Session on request start"のアイデアは、物事を整理する最も簡単な方法のように見え続けています。
関連
-
[解決済み] Pythonでシングルトンを作成する
-
[解決済み] pandasを使った "大量データ "ワークフロー【終了しました
-
[解決済み] SQLAlchemy ORDER BY DESCENDING?
-
[解決済み] SQLAlchemy: flush() と commit() の違いは何ですか?
-
[解決済み] SQLAlchemy: 日付フィールドをフィルタリングする方法は?
-
[解決済み] Celeryでタスクのステータスを確認するには?
-
[解決済み] Pythonでnumpy.linalg.eigを使用した後の固有値と関連する固有ベクトルのソート
-
[解決済み] pathlib.Pathオブジェクトの絶対パスを取得するには?
-
[解決済み] リストスライスの割り当てはどのように行われるのですか?
-
[解決済み] Pythonを使ってすべてのASCII文字のリストを得るにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] DataFrameの文字列、dtypeがobjectの場合
-
[解決済み] Djangoで2つの日付の間を選択する
-
[解決済み] 小数点以下1桁を取得する[重複]。
-
[解決済み] タプルのリストを複数のリストに変換するには?
-
[解決済み] Python Logging でログメッセージが2回表示される件
-
[解決済み] Pythonによる一対のクロスプロダクト [重複] (英語)
-
[解決済み] asyncio.ensure_future vs. BaseEventLoop.create_task vs. simple coroutine?
-
[解決済み] Pythonでnumpy.linalg.eigを使用した後の固有値と関連する固有ベクトルのソート
-
[解決済み] and "と "or "はブール値以外ではどのように作用するか?
-
[解決済み] 乱数の行列を作成する簡単な方法