Flask/SQLAlchemyが設定されていない場合、新しいデータベース接続を作成するにはどうすればよいですか?
頻繁にアクセスしないPython/FlaskサーバーはSQLAlchemyを使用します。サーバーがなくなりました」というエラーが表示されます。その後のページビューは問題ありませんが、この最初のエラーはプロには見えません。
私はこれを処理する正しい方法を知りたいです-この場合約4日間である「本当に長い時間を作る」のようなアドバイスは正しくないようです。データベース接続の欠如をテストし、必要に応じて作成するにはどうすればよいですか?
私は以前これで問題を抱えていましたが、それを処理する方法はセッションを維持しないことです。問題は、接続を長時間開いたままにしようとしていることです。代わりに、__init__.py
またはどこにでもインポートするユーティリティパッケージ内:
from sqlalchemy.orm import scoped_session, sessionmaker
Session = scoped_session( sessionmaker() )
次に、エンジンとメタデータを一度セットアップします。これにより、接続/切断するたびに構成メカニズムをスキップできます。その後、次のようにdbを実行できます。
session = Session()
someObject = session.query( someMappedClass ).get( someId )
# use session like normal ...
session.close()
古いオブジェクトを保持し、セッションを開いたままにしたくない場合は、上記のパターンを使用して、次のように古いオブジェクトを再利用できます。
session = Session()
someObject = session.merge( someObject )
# more db stuff
session.close()
ポイントは、セッションを開き、作業を行い、セッションを終了することです。これにより、タイムアウトが非常によく回避されます。 .mergeおよび.addには多くのオプションがあり、デタッチされたオブジェクトに加えた変更を含めるか、dbから新しいデータを読み込むことができます。ドキュメントは非常に冗長ですが、探しているものがわかれば、少し見つけやすいかもしれません。
実際にそこに到達し、MySQLが「消滅」するのを防ぐには、接続プールを長く開いたままにして、古い接続をチェックアウトするという接続プールの問題を解決する必要があります。
新しい接続を取得するには、pool_recycle
オプションのcreate_engine
呼び出し。これを設定pool_recycle
は、既存の接続を返す代わりに、新しい接続を作成するチェックアウト間の接続プール内の秒数です。
私は同様の問題を抱えていましたが、私にとっては、各セッションの5分から2時間の間のどこかに「MySQLがなくなった」というエラーが表示されました。
Flask-SQLAlchemyを使用しているため、アイドル状態の接続を閉じることになっていますが、接続が数時間以上アイドル状態になっていない限り、それを行っているようには見えませんでした。
最終的には、次のFlask-SQLAlchemy設定に絞り込みました。
app.config['SQLALCHEMY_POOL_SIZE'] = 100
app.config['SQLALCHEMY_POOL_RECYCLE'] = 280
これらのデフォルト設定は、それぞれ10および7200(2時間)です。
環境に合わせてこれらの設定をいじるだけです。
たとえば、SQLALCHEMY_POOL_RECYCLEを3600に設定する必要があることを多くの場所で読みましたが、それはうまくいきませんでした。私はPythonAnywhereでホストしており、5分(300秒)後にアイドル状態のMySQL接続を切断します。したがって、私の値を300未満に設定すると、問題が解決しました。
私はこの問題にあまりにも多くの時間を無駄にしたので、これが他の人の助けになることを願っています。
http://flask-sqlalchemy.pocoo.org/2.1/config/#configuration-keys
2018年の回答:SQLAlchemy v1.2.0 +では、この問題に対処するために利用可能な 接続プールの事前ping 機能があります「MySQLサーバーがなくなりました」。
接続プールの事前ping-接続プールには、接続チェックアウトごとにプールされた接続の「活性」をテストするオプションの「事前ping」機能が含まれ、データベースが切断された場合にDBAPI接続を透過的にリサイクルします。この機能により、「プールリサイクル」フラグが不要になり、データベースの再起動後にプールされた接続が使用されたときに発生するエラーの問題もなくなります。
新しい引数を使用すると、チェックアウト時の接続の悲観的なテストが可能です。
engine = create_engine("mysql+pymysql://user:pw@Host/db", pool_pre_ping=True)
Flask-SQLAlchemyを使用している場合:
修正が利用できるようです: https://github.com/mitsuhiko/flask-sqlalchemy/issues/2
悲しいことに、デフォルトのインストール(pip install flask-sqlalchemy)は、特にこの問題に関して、まだパッチを適切に適用していません: https://github.com/e-dard/flask-sqlalchemy/commit/cf659f346e005d34257d256fa4c42889741fc31f
Githubから最新バージョンを入手すると修正されます。
このエラーが発生したとき、サイズが〜1MBのLONGBLOB
/LargeBinary
イメージを保存していました。 MySQLのmax_allowed_packet
構成設定を調整する必要がありました。
mysqld --max-allowed-packet=16M
を使用しました
プールを使用する場合、recyleをDB wait_timeoutのwait_timeoutが60未満になるように設定する必要があります。したがって、40をrecyleに設定します。
from sqlalchemy.pool import Pool
pool.QueuePool(self.get_connection, max_overflow=0,pool_size=40,recycle=50)