今回は以下のようなエラーが出たのでそれの原因と解決方法を残します。
(pymysql.err.OperationalError) (2006, \"MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))\").......
エラーはこんな時に出ていました。
- 検証環境にて、翌日の一番最初のapiを叩く時(ログイン)で何度かエラーが発生して、何度か試すとエラーがなくなる。
Table of Contents
環境
このエラーが発生していた環境は以下です。
- バックエンド: Python(FastAPI, pymysql)
- フロントエンド: Next.js
- DB: Mysql
今回は案件の都合で全てdockerコンテナを立てて対応しました。
原因
エラーの通りなのですが、バックエンドとMySQLとの接続が切れていたのが原因でした。
今回はSQLAlchemyをORMとして使っていたので、この設定が間違えていたようです。
たまにバックエンドから接続してあげないと、MySQLとの接続が途切れるようですね。(Laravalとかだと特にこんなエラーが出たイメージはないんだけどなあ)
解決方法
はい、今回は簡単。
MySQLとの接続設定をしているファイルにpool_pre_ping
というのを追加してあげる必要があるようです。
settings.py
import os
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
_MYSQL_USER = os.environ["MYSQL_USER"]
_MYSQL_PASSWORD = os.environ["MYSQL_PASSWORD"]
_MYSQL_HOST = os.environ["MYSQL_HOST"]
SQLALCHEMY_ADMIN_DB_URL = f"mysql+pymysql://{_MYSQL_USER}:{_MYSQL_PASSWORD}@{_MYSQL_HOST}/db"
engine = create_engine(SQLALCHEMY_ADMIN_DB_URL, pool_pre_ping=True)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
↑で、pool_pre_ping=True
を追加してあげるとエラーはなくなりました!
まとめ
mysqlの設定が悪いんかなぁとか思っていたら以外とPython側の設定をいじってあげることで解決しました。
打ち手を手当たり次第に出して試すより、色々考えて最適な打ち手を出すのが大切っすね。