TimeOutを返すSql Alchemyアプリケーションがあります。
TimeoutError:サイズ5オーバーフロー10のQueuePool制限に達した、接続がタイムアウトした、タイムアウト30
私は別の投稿で、セッションを閉じないときにこれが起こることを読んでいますが、これが私のコードに当てはまるかどうかわかりません:
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
その後、別のpythonファイルで、2つの関数でデータを収集していますが、init.pyで初期化したDBSessionを使用しています。
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()
セッション変数は次のように作成されます。
#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()))
セッションはinit.pyで作成され、以降のコードでは使用するだけです。どの時点でセッションを閉じる必要がありますか?または、プールサイズを管理するために他に何をする必要がありますか?
関数create_engine
にパラメータpool_sizeおよびmax_overflowを追加することにより、プールサイズを管理できます。
engine = create_engine("mysql://" + loadConfigVar("user") + ":" + loadConfigVar("password") + "@" + loadConfigVar("Host") + "/" + loadConfigVar("schema"),
pool_size=20, max_overflow=0)
参照は こちら です
セッションを閉じる必要はありませんが、トランザクションが完了したら接続を閉じる必要があります。交換:
rescount = DBSession.connection().execute("select resource_id,count(resource_id) as total FROM resourcestats")
沿って:
connection = DBSession.connection()
try:
rescount = connection.execute("select resource_id,count(resource_id) as total FROM resourcestats")
#do something
finally:
connection.close()
参照は こちら です
また、特定の期間が経過するとmysqlの古い接続が閉じられることに注意してください(この期間はMySQLで設定できますが、デフォルト値は覚えていません)。したがって、pool_recycle値をエンジン作成に渡す必要があります。
コードに次のメソッドを追加します。すべての未使用/ハングしている接続を自動的に閉じ、コードのボトルネックを防ぎます。特に、次の構文Model.query.filter_by(attribute = var).first()および関係/遅延読み込みを使用している場合。
@app.teardown_appcontext
def shutdown_session(exception=None):
db.session.remove()
これに関するドキュメントはこちらから入手できます。 http://flask.pocoo.org/docs/1.0/appcontext/