2013-07-31 24 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

不错的发现,更新我的片段的完整性 –

相关问题