1

I have a Flask application running on PythonAnywhere and a PostgreSQL managed database from DigitalOcean. I'm using Flask-SQLAlchemy to connect to the database.

My app works fine locally when connecting to the remote database. However, the app fails when I run it on PythonAnywhere. I suspect that it's uWSGI's multiple workers that are causing the problem, as described on this Stack Overflow post: uWSGI, Flask, sqlalchemy, and postgres: SSL error: decryption failed or bad record mac

This is the error message that I get

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) SSL error: decryption failed or bad record mac

The error is triggered by a simple Flask-SQLAlchemy method:

user = User.query.get(id)

The other Stack Overflow post provided a solution where I can change the uWSGI's configuration. But in PythonAnywhere, I am unable modify the uWSGI's configuration. Also, disposing the database engine after initializing the app did not resolve the issue. Is there an alternate fix?

Edit 1: I have a paid account.

2
  • Do you have a free account? If so, you won't be able to connect with external postgres server on PythonAnywhere. Commented Dec 21, 2020 at 11:03
  • @caseneuve I have a paid account. Commented Dec 21, 2020 at 13:57

1 Answer 1

2

Disposing the database engine after initializing the app DID resolve the issue. This is a link to the post that helped me: https://github.com/pallets/flask-sqlalchemy/issues/745#issuecomment-499970525

This is how I fixed it in my code.

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from tms_sola.config import Config  # my custom config object

db = SQLAlchemy()

def create_app(config_class=Config):
    app = Flask(__name__)
    app.config.from_object(config_class)
    app.app_context().push()

    with app.app_context(): 
        db.init_app(app)

        # https://github.com/pallets/flask-sqlalchemy/issues/745#issuecomment-499970525
        db.session.remove()
        db.engine.dispose()

    from tms_sola.blueprints.some_blueprint.routes import some_blueprint

    # https://github.com/pallets/flask-sqlalchemy/issues/745#issuecomment-499970525
    db.session.remove()
    db.engine.dispose()

    return app
Sign up to request clarification or add additional context in comments.

2 Comments

PythonAnywhere dev here -- that makes sense. What was happening was that when your site initially started up, it was creating a connection to the Postgres instance. It did your init stuff, and then continued with the full website initialization and handed over to PythonAnywhere, which then cloned your single startup process into multiple ones. Unfortunately they all had copies of the same connection that had previously been created, so when they tried to use it, they tripped over each other. Your disposal of the DB engine cleared the connection pool so they all started with fresh empty ones.
Do you think the same solution would work for a gunicorn web server?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.