[英]Does SQLAlchemy reset the database session between SQLAlchemy Sessions from the same connection?
SQLAlchemy 使用連接池。 這意味着可以在不同的 SQLAlchemy 會話中重復使用相同的連接。 但是,單個 SQLAlchemy 會話包含在其自身中並在關閉后被丟棄。 然而,連接保持“活動”。
我想使用 set_config 將某些內容保存到 Postgresql 中的數據庫會話存儲中:
PERFORM set_config('session.storage', 'remember-me-across-this-session', false)
現在,這是在數據庫會話的范圍內。 我的問題是:當 SQLAlchemy 使用相同的連接創建一個新的 SQLAlchemy 會話時,這是否也會創建一個新的數據庫會話,或者該連接是否會在其整個生命周期內重復使用相同的數據庫會話?
注意:我已經嘗試通過將所有相關池大小設置為最小值(max_overflow 0、pool_size 1、pool_recycle 600)然后運行以下腳本(簡化)來對此進行測試:
print(DBSESSION.execute(text("SELECT set_config('session.storage', 'remember-me-across-this-session', false)")).first())
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
transaction.commit()
DBSESSION.close()
for _ in range(5):
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
transaction.commit()
DBSESSION.close()
該測試沒有“記住”循環中以下會話的第一行中設置的值,從而確認數據庫會話確實在同一連接的 SQLAlchemy 會話之間重置。 然而,因為這是邏輯的關鍵部分,我希望得到第二意見/肯定,以確保我沒有搞砸。
不,不是的。
SQLAlchemy session.close()
關閉剩余的 SQLAlchemy 事務,這些事務在它們的連接上調用ROLLBACK
並將它們返回到池中。
一個 SQLAlchemy Session 通常代表一個或多個事務的范圍,在特定的數據庫連接上。
會話“與 TCP 連接同義”。
SET
從https://www.postgresql.org/docs/9.3/sql-set.html :
如果
SET
(或等效的SET SESSION
)在稍后被中止的事務中發出,則SET
命令的效果在事務回滾時消失。 一旦周圍的事務被提交,效果將持續到會話結束,除非被另一個SET
覆蓋。
在測試中,沒有任何操作導致 Zope 將會話狀態標記為已更改。
Zope transaction.commit()
檢查會話狀態是否改變:
session.close()
並將其對 SQLAlchemy Transaction 的引用設置為None
。
ROLLBACK
。
SET
, SET
命令的效果消失了。SET
,效果將持續到 (PostgreSQL) 會話結束。 您可以通過將會話顯式標記為已更改來驗證Else
情況:
print(DBSESSION.execute(text("SELECT set_config('session.storage', 'remember-me-across-this-session', false)")).first())
print(DBSESSION.execute(text("SELECT current_setting('session.storage')")).first())
mark_changed(DBSESSION.registry()) # Add this
transaction.commit()
注意:由於transaction.commit()
和transaction.abort()
已經隱式調用session.close()
,因此對DBSESSION.close()
的后續調用實際上什么都不做。
為sqlalchemy.events.PoolEvents.checkin
添加事件偵聽器並調用RESET
。
@event.listens_for(engine, 'checkin')
def receive_checkin(dbapi_connection, connection_record):
cursor = dbapi_connection.cursor()
cursor.execute('RESET session.storage')
# cursor.execute('RESET ALL')
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.