Flask unittest和sqlalchemy使用所有连接 [英] Flask unittest and sqlalchemy using all connections

查看:217
本文介绍了Flask unittest和sqlalchemy使用所有连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我大概有100个单元测试之后,我刚刚遇到了一个在我的烧录应用上运行单元测试的问题。所有的单元测试都会通过,但是一次运行时会失败,并显示以下错误:

$ $ $ $ $ $ $ OperationalError :( OperationalError)致命错误:剩余的连接槽被保留用于非复制超级用户连接

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

这个人 Flask单元测试用SQLAlchemy和PostgreSQL耗尽数据库连接看起来像他们有相同的确切问题。 Mike / Zzzeek(sqlalchemy dev)甚至回应说,可能在create_app()中发生了一些事情,所以我在下面也包括了这一点。



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

#test.py
$ b

 类TestCase(DataMixin,Base) :
Base test class

def create_app(self):
return create_app(TestConfig())
$ b $ 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__)

#配置
app.config.from_object(BaseConfig())
if config不是None:
app.config.from_object(config)

#扩展
db.init_app(app)
mail.init_app(app)
bcrypt.init_app(app)

#蓝图
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.setup_app(app,add_context_processor = True)
login_manager.login_view =accounts.login
login_manager.user_callback = load_user

#模板
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
如果current_user.is_authenticated():
cart = current_user .get_cart()
返回字典(cart = cart)

#错误处理
@ app.errorhandler(404)
def page_not_found(error):
return render_template('404.html'),404

return app


解决方案

我在这里找到答案 - https://stackoverflow.com/ a / 17998485/1870623 和一个伟大的探索在这里 - https://stackoverflow.com/a/16390645/1870623



解决方法是将 db.get_engine(self.app).dispose()添加到tearDown()

 类TestCase(Base):
def setUp(self):
db.create_all ()
$ b $ def tearDown(self):
db.session.remove()
db.drop_all()
db.get_engine(self.app).dispose ()#这个


I've just run into an issue running unittests on my flask app after I had roughly 100 unittests. All unittests will pass, but when run all at once they will fail with the following error:

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

Everything is running in a virtualbox/vagrant/ubuntu12.04 instance on local machine. My postgres max_connections is set to 100 so I'm assuming that the connections aren't closing and after running 100 tests I use up all the available ones.

This person Flask unit tests with SQLAlchemy and PostgreSQL exhausts db connections looks like they are having the same exact problem. Mike/Zzzeek (sqlalchemy dev) even responded to it saying that something may be happening in create_app() so I've included that as well below.

Does this mean I'm not closing my connections somewhere? All of these errors are triggered by db.create_all() in my setUp() method of my unittest.

# test.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

解决方案

I found the answer here -- https://stackoverflow.com/a/17998485/1870623 and a great explination here -- https://stackoverflow.com/a/16390645/1870623

The solution is to add db.get_engine(self.app).dispose() to the tearDown()

class TestCase(Base):
    def setUp(self):
        db.create_all()

    def tearDown(self):
        db.session.remove()
        db.drop_all()
        db.get_engine(self.app).dispose() # This

这篇关于Flask unittest和sqlalchemy使用所有连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆