postgresql – 如何使Flask SQLAlchemy重用数据库连接?
发布时间:2020-12-13 16:37:24 所属栏目:百科 来源:网络整理
导读:我似乎无法让我的Flask应用程序关闭或重新使用数据库连接。我使用PostgreSQL 9.1.3和 Flask==0.8Flask-SQLAlchemy==0.16psycopg2==2.4.5 当我的测试套件运行打开的连接数爬到20(在postgresql.conf中的max_connections设置),然后我看到: OperationalError:
我似乎无法让我的Flask应用程序关闭或重新使用数据库连接。我使用PostgreSQL 9.1.3和
Flask==0.8 Flask-SQLAlchemy==0.16 psycopg2==2.4.5 当我的测试套件运行打开的连接数爬到20(在postgresql.conf中的max_connections设置),然后我看到: OperationalError: (OperationalError) FATAL: sorry,too many clients already None None 我已经将代码缩小到只需调用create_all和drop_all(但不会发出任何sql,因为没有模型)。 我看到在日志中检入和取出的连接: DEBUG:sqlalchemy.pool.QueuePool:Connection <connection object at 0x101c1dff0; dsn: 'dbname=cx_test host=localhost',closed: 0> checked out from pool DEBUG:sqlalchemy.pool.QueuePool:Connection <connection object at 0x101c1dff0; dsn: 'dbname=cx_test host=localhost',closed: 0> being returned to pool WARNING:root:impl <-------- That's the test running DEBUG:sqlalchemy.pool.QueuePool:Connection <connection object at 0x101c1dff0; dsn: 'dbname=cx_test host=localhost',closed: 0> being returned to pool 对于每个测试运行,连接的地址(“xyz的连接对象”部分)是不同的。我怀疑这与问题有关,但我不知道如何进一步调查。 下面的代码在新的venv中再现了问题: from flask import Flask from flask.ext.sqlalchemy import SQLAlchemy from unittest import TestCase import logging logging.basicConfig(level=logging.DEBUG) logging.getLogger('sqlalchemy.pool').setLevel(logging.DEBUG) logging.getLogger('sqlalchemy.engine').setLevel(logging.DEBUG) logging.getLogger('sqlalchemy.dialects').setLevel(logging.DEBUG) logging.getLogger('sqlalchemy.orm').setLevel(logging.DEBUG) db = SQLAlchemy() def create_app(config=None): app = Flask(__name__) app.config.from_object(config) db.init_app(app) return app class AppTestCase(TestCase): SQLALCHEMY_DATABASE_URI = "postgresql://localhost/cx_test" TESTING = True def create_app(self): return create_app(self) def setUp(self): self.app = self.create_app() self.client = self.app.test_client() self._ctx = self.app.test_request_context() self._ctx.push() db.create_all() def tearDown(self): db.session.remove() db.drop_all() self._ctx.pop() class TestModel(AppTestCase): def impl(self): logging.warn("impl") pass def test_01(self): self.impl() def test_02(self): self.impl() def test_03(self): self.impl() def test_04(self): self.impl() def test_05(self): self.impl() def test_06(self): self.impl() def test_07(self): self.impl() def test_08(self): self.impl() def test_09(self): self.impl() def test_10(self): self.impl() def test_11(self): self.impl() def test_12(self): self.impl() def test_13(self): self.impl() def test_14(self): self.impl() def test_15(self): self.impl() def test_16(self): self.impl() def test_17(self): self.impl() def test_18(self): self.impl() def test_19(self): self.impl() if __name__ == "__main__": import unittest unittest.main() 这是我第一次在烧瓶中使用应用程序工厂,我从Flask-SQLAlchemy docs.部分复制了这个代码。Elseware这些文档提到在错误的上下文中使用数据库会导致连接泄漏 – 也许我正在做不正确的init?
在阅读SQLAlchemy文档和一些数据库实例之后,我终于得到了解决方案。在tearDown()中添加db.get_engine(self.app).dispose(),使其看起来像:
def tearDown(self): db.session.remove() db.drop_all() db.get_engine(self.app).dispose() self._ctx.pop() (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |