how to fix "OperationalError: (psycopg2.OperationalError) server closed the connection unexpectedly"
Same logic for sqlalchemy.orm, ( on which flask_sqlalchemy is based btw )
engine = sqlalchemy.create_engine(connection_string, pool_pre_ping=True)
More protection strategies can be setup such as it is described in the doc: https://docs.sqlalchemy.org/en/13/core/pooling.html#disconnect-handling-pessimistic
For example, here is my engine instantiation:
engine = sqlalchemy.create_engine(connection_string, pool_size=10, max_overflow=2, pool_recycle=300, pool_pre_ping=True, pool_use_lifo=True)sqlalchemy.orm.sessionmaker(bind=engine, query_cls=RetryingQuery)
For RetryingQuery code, cf: Retry failed sqlalchemy queries
Building on the Solution in the answer and the info from @MaxBlax360's answer. I think the proper way to set these config values in Flask-SQLAlchemy is by setting app.config['SQLALCHEMY_ENGINE_OPTIONS']
:
from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)# pool_pre_ping should help handle DB connection dropsapp.config['SQLALCHEMY_ENGINE_OPTIONS'] = {"pool_pre_ping": True} app.config['SQLALCHEMY_DATABASE_URI'] = \ f'postgresql+psycopg2://{POSTGRES_USER}:{dbpass}@{POSTGRES_HOST}:{POSTGRES_PORT}/{POSTGRES_DBNAME}'db = SQLAlchemy(app)
I'm posting my own answer to this, since none of the above addressed my particular setup (Postgres 12.2, SQLAlchemy 1.3).
To stop the OperationalError
s, I had to pass in some additional connect_args
to create_engine
:
create_engine( connection_string, pool_pre_ping=True, connect_args={ "keepalives": 1, "keepalives_idle": 30, "keepalives_interval": 10, "keepalives_count": 5, } )