title: FastAPI - (psycopg2.OperationalError) server closed the connection unexpectedly
body: <p>I have a web app built with FastAPI and SQLAlchemy and it works OK locally with Docker but the db query fails with an error on DigitalOcean with hosted Postgres DB:</p>
  <blockquote>
  <p>(psycopg2.OperationalError) server closed the connection unexpectedly\n\tThis probably means the server terminated abnormally\n\tbefore or while processing the request.\n\n(Background on this error at: <a href="http://sqlalche.me/e/14/e3q8" rel="noreferrer">http://sqlalche.me/e/14/e3q8</a>)&quot;}</p>
  </blockquote>
  <p>I had this error before while working with Flask and the problem was I had to set the engine option <code>pool_pre_ping=True</code> and add my cluster/droplet IP to the database 's trusted sources. But looks like with FastAPI this is not enough. What else can I do to successfully perform queries?</p>
  <p><strong>Background</strong></p>
  <ul>
  <li>Python 3.9</li>
  <li>DigitalOcean hosted Postgres 13</li>
  <li>psycopg==2.8.6 but also tried 2.8.5 (which 100% worked in the similar case with Flask for me) and 2.7.4 just in case</li>
  <li>I have <code>pool_pre_ping=True</code> set
  <ul>
  <li>I checked it is really set to <code>True</code> right before a request using <code>session.get_bind().pool._pre_ping</code> and it is actually <code>True</code></li>
  </ul>
  </li>
  <li>I checked that my cluster nodes' IPs are in DB trusted sources</li>
  <li>I run the app with gunicorn using one <code>uvicorn.workers.UvicornH11Worker</code> worker</li>
  <li>I use a middleware to access my db session inside FastAPI enpoints like this:</li>
  </ul>
  <pre class="lang-py prettyprint-override"><code>class DBMiddleware:
      def __init__(self, app, sqlalchemy_uri):
          self.app = app
          self.sqlalchemy_uri = sqlalchemy_uri
          self.engine = None
  
      async def __call__(self, scope: Scope, receive: Receive, send: Send):
          if scope['type'] not in ['http', 'websocket']:
              await self.app(scope, receive, send)
              return
  
          if not self.engine:
              self.engine = create_engine(self.sqlalchemy_uri, pool_pre_ping=True, pool_recycle=3600)
  
          session = Session(autoflush=False, autocommit=False, bind=self.engine)
          scope['db'] = session
          await self.app(scope, receive, send)
          session.close()
  
  
  def get_db(request: Request):
      return request.scope.get('db')
  
  ...
  
  @app.on_event('startup')
  async def startup():
      ...
      app.add_middleware(DBMiddleware, sqlalchemy_uri=config.SQLALCHEMY_DATABASE_URI)
  
  @router.post('/endpoint')
  async def endpoint(db: Session = Depends(get_db)):
      ...
  </code></pre>
  <ul>
  <li>Also I tried to use the globally defined engine with session context (just to check) but still has the same behaviour so looks like middleware is not a problem</li>
  <li>No useful logs from the Postgres side</li>
  <li>I also tried to change my app query to just <code>db.execute('SELECT 1')</code> in case some weird timeouts or something - still the same</li>
  <li>I read a lot of similar issues in general about psycopg2 and very few about FastAPI that I could found e.g. <a href="https://github.com/tiangolo/full-stack-fastapi-postgresql/issues/290" rel="noreferrer">this</a> and <a href="https://github.com/tiangolo/fastapi/issues/726" rel="noreferrer">that</a> and official docs of course.</li>
  </ul>
  <p>After all that tries the issue is still there. I'm not too aware of <code>async</code> Python so I can suspect the problem can be in the way how the connection is shared or something (but I use only one worker at the moment).</p>
  <p><strong>UPDATE</strong></p>
  <p>I tried to switch to <code>asyncpg</code> (docs: <a href="https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html" rel="noreferrer">https://docs.sqlalchemy.org/en/14/orm/extensions/asyncio.html</a>). Also works locally but on DigitalOcean query hangs and I receive the following error:</p>
  <pre><code>[Errno 104] Connection reset by peer
  </code></pre>
  <p>Looks like the reason is the same but the error looks different for asyncpg.</p>
  <p>Also tried to create a connection pool on DigitalOcean and connect to it - still the same error.</p>