我使用的是python 3.3,pyramid,sqlalchemy,psygopg2。我使用测试postgres db进行单元测试。我有101个单元测试设置为鼻子运行。在测试101我得到:
nose.proxy.OperationalError :( OperationalError)致命:抱歉,已有太多客户
从追溯中可以看出,异常是在
中引发的....... / venv / lib / python3.3 / site-packages / SQLAlchemy-0.8.2-py3.3.egg / sqlalchemy / pool.py&#34;,第368行,在__connect < / p>
connection = self.__pool._creator()
也许每次测试后tearDown()都没有运行?一次不是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()
......
我将dbsession传递给TestApp和TestUser类......我认为这是问题的根源,但我不确定。
非常感谢任何帮助。感谢。
答案 0 :(得分:1)
Pyramid与SQLAlchemy无关。 Pyramid的API中没有任何地方可以以Pyramid真正关心的方式链接任何SQLAlchemy配置。因此,金字塔的testing.tearDown()
对连接没有任何作用。怎么可能呢?它不知道它们存在。
您正在使用带有单元测试的作用域会话,这实际上没有多大意义,因为您的单元测试可能没有线程化。所以现在你正在创建threadlocal会话而不是清理它们。它们不是垃圾收集因为它们是线程本地的。您也没有手动关闭这些连接,因此连接池认为它们仍在使用中。
您的测试中是否需要ZopeTransactionExtension
?您是在测试中使用transaction
包还是pyramid_tm
?在测试中,如果你不知道什么是什么,那么它就不应该存在。您是通过create_all()
方法致电setUp()
了吗?因为我会对数据库进行内省并在每个请求上创建表格,这将会很慢。哎哟。
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()