gpt4 book ai didi

postgresql - Flask unittest 和 sqlalchemy 使用所有连接

转载 作者:行者123 更新时间:2023-11-29 11:30:24 26 4
gpt4 key购买 nike

在我进行了大约 100 次单元测试后,我刚刚在我的 Flask 应用程序上运行单元测试时遇到了问题。所有单元测试都会通过,但是当一次运行所有单元测试时,它们将失败并出现以下错误:

OperationalError: (OperationalError) FATAL:  remaining connection slots are reserved for non-replication superuser connections

一切都在本地机器上的 virtualbox/vagrant/ubuntu12.04 实例中运行。我的 postgres max_connections 设置为 100,所以我假设连接没有关闭,并且在运行 100 次测试后我用完了所有可用的连接。

此人Flask unit tests with SQLAlchemy and PostgreSQL exhausts db connections看起来他们有同样的问题。 Mike/Zzzeek(sqlalchemy 开发人员)甚至回应说 create_app() 中可能发生了某些事情,因此我也将其包含在下面。

这是否意味着我没有关闭某个地方的连接?所有这些错误都是由单元测试的 setUp() 方法中的 db.create_all() 触发的。

#测试.py

class TestCase(DataMixin, Base):
"""Base test class"""

def create_app(self):
return create_app(TestConfig())

def setUp(self):
db.create_all()

def tearDown(self):
db.session.remove()
db.drop_all()

#app.py

def create_app(config=None):
app = Flask(__name__)

# Config
app.config.from_object(BaseConfig())
if config is not None:
app.config.from_object(config)

# Extensions
db.init_app(app)
mail.init_app(app)
bcrypt.init_app(app)

# Blueprints
app.register_blueprint(core_blueprint, url_prefix='/')
app.register_blueprint(accounts_blueprint, url_prefix='/account')
app.register_blueprint(admin_blueprint, url_prefix='/admin')
app.register_blueprint(cart_blueprint, url_prefix='/cart')

# Login Manager
login_manager.setup_app(app, add_context_processor=True)
login_manager.login_view = "accounts.login"
login_manager.user_callback = load_user

# Templates
app.jinja_env.globals['is_admin'] = is_admin
app.jinja_env.globals['is_staff'] = is_staff

@app.context_processor
def inject_cart():
cart = count = None
if current_user.is_authenticated():
cart = current_user.get_cart()
return dict(cart=cart)

# Error Handling
@app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'), 404

return app

最佳答案

更新:已测试并修复

您可以使用子 session 并在每次测试后进行回滚,而不是每次都建立新连接并重新创建数据库(速度慢)。

连接被重用,因此这也解决了您遇到的问题。

class TestCase(Base):

@classmethod
def setUpClass(cls):
cls.app = create_app(MyConfig())
cls.client = cls.app.test_client()
cls._ctx = cls.app.test_request_context()
cls._ctx.push()
db.create_all()

@classmethod
def tearDownClass(cls):
db.session.remove()
db.drop_all()
db.get_engine(cls.app).dispose()

def setUp(self):
self._ctx = self.app.test_request_context()
self._ctx.push()
db.session.begin(subtransactions=True)

def tearDown(self):
db.session.rollback()
db.session.close()
self._ctx.pop()

如果您还需要为每个测试创建一个应用程序实例,只需将其添加到 setUp 方法中,但也将其保留在 setUpClass 中。

下面的完整测试示例需要 flask_sqlalchemy 和 psycopg2。创建一个名为“test”的测试数据库,并将其连接限制设置为 15。

from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from unittest import TestCase as Base


db = SQLAlchemy()

def create_app(config=None):
app = Flask(__name__)
app.config.from_object(config)
db.init_app(app)
return app


class MyConfig(object):
SQLALCHEMY_DATABASE_URI = "postgresql://localhost/test"
TESTING = True


class TestCase(Base):
@classmethod
def setUpClass(cls):
cls.app = create_app(MyConfig())
cls.client = cls.app.test_client()
cls._ctx = cls.app.test_request_context()
cls._ctx.push()
db.create_all()

@classmethod
def tearDownClass(cls):
db.session.remove()
db.drop_all()

def setUp(self):
self._ctx = self.app.test_request_context()
self._ctx.push()
db.session.begin(subtransactions=True)

def tearDown(self):
db.session.rollback()
db.session.close()
self._ctx.pop()


class TestModel(TestCase):

def test_01(self):
pass

def test_02(self):
pass

def test_03(self):
pass

def test_04(self):
pass

def test_05(self):
pass

def test_06(self):
pass

def test_07(self):
pass

def test_08(self):
pass

def test_09(self):
pass

def test_10(self):
pass

def test_11(self):
pass

def test_12(self):
pass

def test_13(self):
pass

def test_14(self):
pass

def test_15(self):
pass

def test_16(self):
pass


if __name__ == "__main__":
import unittest
unittest.main()

关于postgresql - Flask unittest 和 sqlalchemy 使用所有连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18291180/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com