2014-07-25 20 views
14

Ho un'applicazione Sql alchimia che sta tornando TimeOut:Sql Alchemy QueuePool limite di overflow

TimeoutError: QueuePool limit of size 5 overflow 10 reached, connection timed out, timeout 30

ho letto in un altro posto che questo accade quando non chiudere la sessione, ma non so se questo vale per il mio codice:

mi collego al database nel 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 

Poi in un altro file python che sto raccogliendo alcuni dati in due funzioni, ma utilizzando DBSession che ho inizializzato in init.py:

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() 

Le variabili di sessione sono creati in questo modo:

#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())) 

perché la sessione viene creata nel init.py e nella successiva di codice ho appena uso; a che punto devo chiudere la sessione? O cos'altro devo fare per gestire le dimensioni del pool?

+0

Nel secondo frammento di codice, dove io s 'transazione' definita? –

+0

Dove si usa 'getResourceStats'? Sembra che metà del codice sia mancante - puoi aggiungere tutto o potrebbe essere impossibile diagnosticare il problema. –

+1

Questo codice funziona così com'è? L'istruzione 'import' sembra davvero strana, in aggiunta ai problemi menzionati da @ TomDton. A che punto si verifica l'errore? È questo l'esempio [Minimal, Complete, Verificable] (http://stackoverflow.com/help/mcve)? IOW, puoi ridurre tutto questo (o significativamente) e mostrare lo stesso comportamento? Sembra che ci sia un sacco di logica aziendale là fuori che è molto improbabile la causa del problema. Prova a rimuoverlo e pubblicando un esempio funzionante (sintatticamente corretto) e sarei felice di aiutarti. – cod3monk3y

risposta

15

È possibile gestire dimensione del pool con l'aggiunta di parametri pool_size e max_overflow in funzione create_engine

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

riferimento è here

Non è necessario chiudere la sessione, ma la connessione dovrebbe essere chiuso dopo la vostra la transazione è stata fatta. Sostituire:

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

By:

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

riferimento è here

Si noti inoltre connessione che di MySQL che sono stati stantio è chiusa dopo un determinato periodo di tempo (questo periodo può essere configurato in MySQL, non ricordo il valore predefinito), quindi è necessario passare il valore pool_recycle alla creazione del motore

Problemi correlati