[英]python sqlalchemy + postgresql program freezes
我遇到了一個奇怪的情況。 我正在為我的程序編寫一些測試用例。 該程序被編寫為在 sqllite 或 postgresqul 上工作,具體取決於偏好。 現在我正在使用 unittest 編寫我的測試代碼。 基本上我在做什么:
def setUp(self):
"""
Reset the database before each test.
"""
if os.path.exists(root_storage):
shutil.rmtree(root_storage)
reset_database()
initialize_startup()
self.project_service = ProjectService()
self.structure_helper = FilesHelper()
user = model.User("test_user", "test_pass", "test_mail@tvb.org",
True, "user")
self.test_user = dao.store_entity(user)
在設置中,我刪除了所有存在的文件夾(由一些測試創建)然后我重置我的數據庫(基本上刪除表級聯)然后我再次初始化數據庫並創建一些將用於測試的服務。
def tearDown(self):
"""
Remove project folders and clean up database.
"""
created_projects = dao.get_projects_for_user(self.test_user.id)
for project in created_projects:
self.structure_helper.remove_project_structure(project.name)
reset_database()
除了創建服務之外,Tear down 做同樣的事情,因為這個測試模塊與其他模塊是同一個套件的一部分,我不希望某些測試留下一些東西。
現在我所有的測試都可以在 sqllite 上運行良好。 使用 postgresql 我遇到了一個非常奇怪的情況:在執行的某個時刻,實際上與運行之間的差異很小(例如一兩個額外的調用),程序只是停止了。 我的意思是沒有產生錯誤,沒有拋出異常,程序只是停止。
現在我唯一能想到的是,不知何故我忘記了在某處打開的連接,並且在我超時並且發生了一些事情之后。 但是我有很多聯系,所以在我開始閱讀所有代碼之前,我會很感激一些建議/意見。
什么可能導致這種行為? 從哪里開始尋找?
問候, 博格丹
基於 PostgreSQL 的應用程序凍結,因為 PG 相當積極地鎖定表,特別是如果在掛起的事務中打開任何連接,它將不允許 DROP 命令繼續,這些連接以任何方式訪問該表(包括 SELECT)。
如果您在 unix 系統上,命令“ps -ef | grep 'post'”將向您顯示所有 Postgresql 進程,您將看到“TABLE 狀態”或任何當前命令的狀態,包括太冷了。 如果您從 pg_stat_activity 視圖中查看 select,您也可以看到它。
所以關鍵是確保沒有待處理的事務存在——這意味着在 DBAPI 級別上,任何結果游標都已關閉,並且當前打開的任何連接都調用了rollback()
,或者以其他方式顯式關閉。 在 SQLAlchemy 中,這意味着任何帶有待處理行的結果集(即ResultProxy
)都已完全耗盡,並且任何Connection
對象已被close()
d,這將它們返回到池並在底層 DBAPI 連接上調用rollback()
。 您需要確保有某種無條件的拆卸代碼,以確保在發出任何 DROP TABLE 類型的命令之前發生這種情況。
至於“我有很多人脈”,你應該控制住它。 當 SQLA 測試套件運行它的 3000 個測試時,我們確保我們完全控制連接,並且通常一次只打開一個連接(不過,在 Pypy 上運行有一些仍然會導致 PG 掛起的行為。它太硬)。 有一個名為AssertionPool
的池 class 可用於此目的,它可確保一次只檢出一個連接,否則會引發信息錯誤(顯示檢出位置)。
我發現這個問題的一個解決方案是在嘗試調用db.session.close()
之前調用db.drop_all()
。 這將在刪除表之前關閉連接,防止 Postgres 鎖定表。
在此處查看對該問題的更深入討論。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.