2013-07-31 30 views
0

我使用python 3.3,pyramid,sqlalchemy,psygopg2。我正在使用postgres db進行單元測試。我有101個單元測試設置爲鼻子運行。在測試101獲得:Python鼻子單元測試已經產生了太多的客戶端

nose.proxy.OperationalError: (OperationalError) FATAL: sorry, too many clients already

它從回溯似乎異常在

......./venv/lib/python3.3/site-packages/SQLAlchemy-0.8.2-py3.3.egg/sqlalchemy/pool.py", line 368, in __connect

connection = self.__pool._creator() 

被拋出也許拆解()每次測試後沒有運行? Postgresql 100的連接池限制是不是一次?

這裏是我的BaseTest類:

class BaseTest(object): 
    def setup(self): 
     self.request = testing.DummyRequest() 
     self.config = testing.setUp(request=self.request) 
     self.config.scan('../models') 
     sqlalchemy_url = 'postgresql://<user>:<pass>@localhost:5432/<db>' 
     engine = create_engine(sqlalchemy_url) 
     DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension())) 
     DBSession.configure(bind=engine) 
     Base.metadata.bind = engine 
     Base.metadata.create_all(engine) 
     self.dbsession = DBSession 

    def tearDown(self): 
     testing.teardown() 

我的測試類從BaseTest繼承:

class TestUser(BaseTest): 
    def __init__(self, dbsession = None): 
     if dbsession: 
      self.dbsession = dbsession 

    def test_create_user(self): 
     ...... 
     ...... 

一個測試類的測試一個多一對多的關係,所以在測試類我首先創建滿足外鍵關係所需的記錄:

from tests.test_user import TestUser 
from tests.test_app import TestApp 
class TestAppUser(BaseTest): 
    def __init__(self, dbsession = None): 
     if dbsession: 
      self.dbsession = dbsession 

    def create_app_user(self): 
     test_app = TestApp(self.dbsession) 
     test_user = TestUser(self.dbsession) 
     test_app.request = testing.DummyRequest() 
     test_user.request = testing.DummyRequest() 
     app = test_app.create_app() 
     user = test_user.create_user() 
     ...... 

我通過將數據庫引入TestApp和TestUser類......我認爲這是問題的根源,但我不確定。

任何幫助,非常感謝。謝謝。

+0

這種類型的推測性調試對於stackoverflow的QA格式來說是很糟糕的。看起來好像你沒有正確地關閉你的連接。 –

+0

@MichaelMerickel:我對「投機調試」表示抱歉。我不太確定如何說出我遇到的問題/問題。關於正確關閉連接...不應該'tearDown()'函數正確關閉連接? – smoothgrips

+0

問題在於你如何解決SO上的問題,這也讓任何人都難以回答。我建議將其重新編寫爲「這裏是相關的代碼,我所做的和這裏的錯誤」。您沒有向我們展示您的任何代碼,因此我們無法提供幫助。 'tearDown'不會做任何你沒有放在那裏的東西,所以我現在怎麼說它正在做什麼? –

回答

1

金字塔與SQLAlchemy無關。 Pyramid的API中沒有任何地方可以將Pyramid實際上關心的任何SQLAlchemy配置連接起來。因此,金字塔的testing.tearDown()不會對連接做任何事情。它怎麼可能?它不知道它們存在。

您正在將範圍會話與單元測試結合使用,這實際上並沒有多大意義,因爲您的單元測試可能不是線程化的。所以現在你正在創建線程本地會話而不是清理它們。他們不是垃圾收集,因爲他們是threadlocal。您也不會手動關閉這些連接,因此連接池認爲它們仍在使用中。

是否有理由在測試中需要ZopeTransactionExtension?你在測試中使用transaction包嗎,或者pyramid_tm?在測試中,如果你不知道什麼是什麼,那麼它不應該在那裏。您從setUp()方法呼叫create_all()?這會很慢,因爲它會在每個請求中反思數據庫並創建表。哎喲。

class BaseTest(object): 
    def setUp(self): 
     self.request = testing.DummyRequest() 
     self.config = testing.setUp(request=self.request) 
     self.config.scan('../models') 
     sqlalchemy_url = 'postgresql://<user>:<pass>@localhost:5432/<db>' 
     self.engine = create_engine(sqlalchemy_url) 
     Base.metadata.create_all(bind=self.engine) 
     self.sessionmaker = sessionmaker(bind=self.engine) 
     self.sessions = [] 

    def makeSession(self, autoclose=True): 
     session = self.sessionmaker() 
     if autoclose: 
      self.sessions.append(session) 

    def tearDown(self): 
     for session in self.sessions: 
      session.close() 
     self.engine.dispose() 
     testing.teardown() 
+0

謝謝你的迴應。你的代碼,我注意到問題仍然存在 那裏。我嘗試在'create_engine'中傳遞'echo_pool = True'並查看日誌。我注意到'session.close()'被調用。於是我嘗試在'setUp'中添加'self.engine = engine',然後在'tearDown'中添加'engine.dispose()',並解決了這個問題。 – smoothgrips

+0

不錯的發現,更新我的片段的完整性 –

相關問題