python - postgres - sqlalchemy password
Sql Alchemy QueuePool lĂmite de desbordamiento (2)
Agregue el siguiente método a su código. Cerrará automáticamente todas las conexiones no utilizadas / colgantes y evitará cuellos de botella en su código. Especialmente si está utilizando la siguiente sintaxis Model.query.filter_by (attribute = var) .first () y las relaciones / carga diferida.
@app.teardown_appcontext
def shutdown_session(exception=None):
db.session.remove()
La documentación sobre esto está disponible aquí: http://flask.pocoo.org/docs/1.0/appcontext/
Tengo una aplicación de Alquimia Sql que está devolviendo TimeOut:
TimeoutError: Se alcanzó el límite de QueuePool de tamaño 5 desbordamiento 10, tiempo de espera de conexión, tiempo de espera 30
Leí en una publicación diferente que esto sucede cuando no cierro la sesión pero no sé si esto se aplica a mi código:
Me conecto a la base de datos en el 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
Luego, en otro archivo de Python, estoy recopilando algunos datos en dos funciones, pero utilizando DBSession que inicialicé en 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()
Las variables de sesión se crean así:
#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()))
Debido a que la sesión se crea en init.py y en el código subsiguiente, simplemente la uso; ¿En qué punto necesito cerrar la sesión? ¿O qué más debo hacer para administrar el tamaño de la piscina?
Puede administrar el tamaño de la agrupación agregando los parámetros pool_size y max_overflow en la función create_engine
engine = create_engine("mysql://" + loadConfigVar("user") + ":" + loadConfigVar("password") + "@" + loadConfigVar("host") + "/" + loadConfigVar("schema"),
pool_size=20, max_overflow=0)
La referencia está here
No es necesario que cierre la sesión, pero la conexión debe cerrarse después de que se haya realizado la transacción. Reemplazar:
rescount = DBSession.connection().execute("select resource_id,count(resource_id) as total FROM resourcestats")
Por:
connection = DBSession.connection()
try:
rescount = connection.execute("select resource_id,count(resource_id) as total FROM resourcestats")
#do something
finally:
connection.close()
La referencia está here
Además, tenga en cuenta que la conexión de mysql que ha estado inactiva se cierra después de un período de tiempo determinado (este período se puede configurar en MySQL, no recuerdo el valor predeterminado), por lo que necesita pasar el valor de pool_recycle a la creación de su motor