Ich kann meine Flask-App scheinbar nicht dazu bringen, DB-Verbindungen zu schließen oder wiederzuverwenden. Ich bin mit PostgreSQL 9.1.3 undWie mache ich Flask SQLAlchemy wiederverwenden Db-Verbindungen?
Flask==0.8
Flask-SQLAlchemy==0.16
psycopg2==2.4.5
Als meine Testsuite der Anzahl der offenen Verbindungen läuft steigt, bis er 20 trifft (die max_connections
Einstellung in postgresql.conf
), dann sehe ich:
OperationalError: (OperationalError) FATAL: sorry, too many clients already
None None
Ich habe den Code auf den Punkt reduziert, wo es nur ruft create_all
und drop_all
(aber keine SQL ausgeben, da es keine Modelle gibt).
Ich sehe Verbindungen in und aus in den Protokollen überprüft werden:
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> 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
Für jeden Test die Adresse der Verbindung ausgeführt werden (das „Verbindungsobjekt an xyz“ Teil) ist anders. Ich vermute, das hat etwas mit dem Problem zu tun, aber ich weiß nicht, wie ich weiter nachforschen soll.
Der folgende Code reproduziert das Problem in einer neuen 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()
Dies ist das erste Mal, dass ich app Fabriken in der Flasche verwendet haben, und ich kopiert diesen Code zum Teil aus dem Flask-SQLAlchemy docs. Elseware Diese Dokumente erwähnen, dass die Verwendung einer Datenbank im falschen Kontext dazu führt, dass Verbindungen auslaufen - vielleicht mache ich die Init falsch?
Dank Van - das löst das Problem mit der Testsuite, aber bedeutet es nicht nur, dass ich weniger Verbindungen lecke? –
@TomDunham: Ich denke, du hast Recht. habe keine postgres, also kann dir da nicht helfen, sorry .. – van