Ben
Ben

Reputation: 5198

flask-session on sqlalchemy does not accept db address info

I am trying to use flask-session to save session data in a MySQL db using SQLAlchemy. It works on my local machine. It also works in a Docker container. However, when I try to run it on Google Cloud, my job fails and I receive the following message...

pymysql.err.OperationalError: (2003, "Can't connect to MySQL server on 'localhost' ([Errno 20] Not a directory)")

Why? I am sending flask and flask-session the DB info as documented here...

flask_app.config[
    'SQLALCHEMY_DATABASE_URI'] = ('mysql+pymysql://' + db_uid + ':' + db_pw + '@' + db_addr + '/' +
                                  globals.admin_schema_name)
flask_app.config['SQLALCHEMY_BINDS'] = {
    'session_bind_key': ('mysql+pymysql://' + db_uid + ':' + db_pw + '@' + db_addr + '/' + globals.admin_schema_name)}
flask_app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app=flask_app, metadata=common.meta)
flask_app.config['SESSION_TYPE'] = 'sqlalchemy'
flask_app.config['SESSION_SQLALCHEMY'] = db
flask_app.config['SESSION_SQLALCHEMY_TABLE'] = 'session'
flask_app.config['SESSION_PERMANENT'] = False  # Session expires when browser is closed
flask_app.config['SESSION_USE_SIGNER'] = True  # Makes the session more secure

flask_app.config['SESSION_SQLALCHEMY_BIND_KEY'] = 'session_bind_key'

flask_app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1)  # Time out after one hour of inactivity
flask_app.config['SQLALCHEMY_ECHO'] = True

flask_app.config['SESSION_COOKIE_HTTPONLY'] = True  # Can't be accessed by JavaScript - helps prevent XSS attacks
flask_app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'

And the relevant variable values are fed to my program via CloudRun environment variables. Here are some of them...

db_addr: /xx_admin_v1?unix_socket=/cloudsql/xxxxx-record-00:us-central1:xx-mysql8

globals.admin_schema_name: xx_admin_v1

I have set up the DB connection in CloudSQL via the UI. To test it, just before initializing the session, I successfully run a SQLAlchemy command against my DB.

I then initialize the session with the following code:

# Initialize the flask session
Session(app=flask_app)

This is the line where the job fails.

Any ideas on why google cloud causes flask-session to ignore the DB info I give it and just try to find my DB on localhost? I should note that, earlier in the program I connect to my DB for other tasks and that all goes smoothly.

Thanks!

Upvotes: 0

Views: 42

Answers (1)

Jack Wotherspoon
Jack Wotherspoon

Reputation: 1979

For the /cloudsql/<PROJECT>:<REGION>:<INSTANCE_NAME> UNIX socket to be reachable via your Cloud Run service you must attach a Cloud SQL connection to your Cloud Run service (doing so spins up the Cloud SQL Proxy listening on the given UNIX socket).

Either via the UI: add cloud sql connection via UI

Or when using the gcloud run deploy you add the --add-cloudsql-instances <PROJECT>:<REGION>:<INSTANCE_NAME> flag.

This step has most likely been omitted, meaning the UNIX socket does not exist for your service, causing the database driver to default back to attempting to reach localhost.

Upvotes: 1

Related Questions