0

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!

3
  • Are you attempting to connect over a Unix socket or a TCP connection? It is hard to help without knowing what you are setting db_addr or globals.admin_schema_name to? Commented Nov 4, 2024 at 16:14
  • @JackWotherspoon Hi, Jack, I've added that information to my posting. The unix_socket portion came from google documentation. Any ideas? Commented Nov 4, 2024 at 21:06
  • When deploying your app to Cloud Run did you add the --add-cloudsql-instances xxxxx-record-00:us-central1:xx-mysql8 to your gcloud run deploy command? Or if you are deploying through the UI you must go to the "Cloud SQL Connections" section and add your instance. Commented Nov 5, 2024 at 18:22

1 Answer 1

1

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.

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

5 Comments

Thank you, Jack. I believe we've added the Cloud SQL connection via the Cloud Run UI. However, I'm out of town and unable to confirm for the rest of the week. I'll definitely check when I'm back in the office.
I was just able to start looking at this again. I have set up the DB connection via the UI. I added details to my original question. I'd appreciate any suggestions you might have.
Is your instance using a Public IP or Private IP address?
I'm connecting to this address: xxxxxx-record-00:us-central1:xx-mysql8 Is that considered a private IP connection? It works for other queries I issue through SQLAlchemy to the same DB.
That is your instance connection name, when creating your Cloud SQL instance, you would have created it with a Public IP or Private IP address, the built-in Cloud SQL Proxy which you are attempting to use only works with Public IP connections is why I ask. Have you looked at using the Cloud SQL Python Connector library? It has all the same benefits as the Proxy but as a native Python package. github.com/GoogleCloudPlatform/cloud-sql-python-connector/tree/…

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.