it-swarm.com.de

SQL-Alchemy QueuePool-Limitüberlauf

Ich habe eine SQL Alchemy-Anwendung, die TimeOut zurückgibt:

TimeoutError: QueuePool-Limit der Größe 5 Überlauf 10 erreicht, Zeitüberschreitung der Verbindung, Zeitüberschreitung 30

Ich habe in einem anderen Beitrag gelesen, dass dies passiert, wenn ich die Sitzung nicht schließe, aber ich weiß nicht, ob dies für meinen Code gilt:

Ich verbinde mich mit der Datenbank in der init.py:

from .dbmodels import (
    DBSession,
    Base,    

engine = create_engine("mysql://" + loadConfigVar("user") + ":" + loadConfigVar("password") + "@" + loadConfigVar("Host") + "/" + loadConfigVar("schema"))

#Sets the engine to the session and the Base model class
DBSession.configure(bind=engine)
Base.metadata.bind = engine

Dann sammle ich in einer anderen Python-Datei einige Daten in zwei Funktionen, benutze aber DBSession, die ich in init.py initialisiert habe:

from .dbmodels import DBSession
from .dbmodels import resourcestatsModel

def getFeaturedGroups(max = 1):

    try:
        #Get the number of download per resource
        transaction.commit()
        rescount = DBSession.connection().execute("select resource_id,count(resource_id) as total FROM resourcestats")

        #Move the data to an array
        resources = []
        data = {}
        for row in rescount:
            data["resource_id"] = row.resource_id
            data["total"] = row.total
            resources.append(data)

        #Get the list of groups
        group_list = toolkit.get_action('group_list')({}, {})
        for group in group_list:
            #Get the details of each group
            group_info = toolkit.get_action('group_show')({}, {'id': group})
            #Count the features of the group
            addFesturedCount(resources,group,group_info)

        #Order the FeaturedGroups by total
        FeaturedGroups.sort(key=lambda x: x["total"],reverse=True)

        print FeaturedGroups
        #Move the data of the group to the result array.
        result = []
        count = 0
        for group in FeaturedGroups:
            group_info = toolkit.get_action('group_show')({}, {'id': group["group_id"]})
            result.append(group_info)
            count = count +1
            if count == max:
                break

        return result
    except:
        return []


    def getResourceStats(resourceID):
        transaction.commit()
        return  DBSession.query(resourcestatsModel).filter_by(resource_id = resourceID).count()

Die Sitzungsvariablen werden folgendermaßen erstellt:

#Basic SQLAlchemy types
from sqlalchemy import (
    Column,
    Text,
    DateTime,
    Integer,
    ForeignKey
    )
# Use SQLAlchemy declarative type
from sqlalchemy.ext.declarative import declarative_base

#
from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    )

#Use Zope' sqlalchemy  transaction manager
from zope.sqlalchemy import ZopeTransactionExtension

#Main plugin session
DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))

Da die Sitzung in der Datei init.py und im nachfolgenden Code erstellt wird, verwende ich sie nur. Wann muss ich die Sitzung beenden? Oder was muss ich noch tun, um die Poolgröße zu verwalten?

23
QLands

Sie können die Poolgröße verwalten, indem Sie die Parameter pool_size und max_overflow in der Funktion create_engine hinzufügen.

engine = create_engine("mysql://" + loadConfigVar("user") + ":" + loadConfigVar("password") + "@" + loadConfigVar("Host") + "/" + loadConfigVar("schema"), 
                        pool_size=20, max_overflow=0)

Referenz ist hier

Sie müssen die Sitzung nicht schließen, aber die Verbindung sollte geschlossen werden, nachdem Ihre Transaktion abgeschlossen wurde . Ersetzen:

rescount = DBSession.connection().execute("select resource_id,count(resource_id) as total FROM resourcestats")

Durch:

connection = DBSession.connection()
try:
    rescount = connection.execute("select resource_id,count(resource_id) as total FROM resourcestats")
    #do something
finally:
    connection.close()

Referenz ist hier

Beachten Sie auch, dass die Verbindung von mysql nach einem bestimmten Zeitraum geschlossen wird (dieser Zeitraum kann in MySQL konfiguriert werden, ich erinnere mich nicht an den Standardwert). Daher müssen Sie den Pool_recycle-Wert an die Engine-Erstellung übergeben

23

Fügen Sie Ihrem Code die folgende Methode hinzu. Es schließt automatisch alle nicht verwendeten/hängenden Verbindungen und verhindert Engpässe in Ihrem Code. Insbesondere wenn Sie die folgende Syntax verwenden: Model.query.filter_by (attribute = var) .first () und Beziehungen/Lazy Loading.

   @app.teardown_appcontext
    def shutdown_session(exception=None):
        db.session.remove()

Dokumentation dazu ist hier verfügbar: http://flask.pocoo.org/docs/1.0/appcontext/