I was following the Connecting to Cloud SQL with Cloud Functions tutorial but my Cloud Function won't connect to the PostgreSQL database.
Here's my function code:
import sqlalchemyconnection_name = "redacted-1234a:asia-northeast3:myinstance2"query_string = dict({"unix_sock": "/cloudsql/{}/.s.PGSQL.5432".format(connection_name)})def insert(request): print(f"Started function - query_string: {query_string}") request_json = request.get_json() stmt = sqlalchemy.text('insert into {} ({}) values ({})'.format("entries", "(guestName, content)", "(\"cloud hello\", \"Got here!\")")) db = sqlalchemy.create_engine( sqlalchemy.engine.url.URL( drivername="postgres+pg8000", username="postgres", password=redacted, database="guestbook", query=query_string, ), pool_size=5, max_overflow=2, pool_timeout=30, pool_recycle=1800 ) print("Created engine") try: with db.connect() as conn: print("Connected to engine") conn.execute(stmt) except Exception as e: return 'Error: {}'.format(str(e)) return 'ok'
When I run it from the "Testing" tab, I get:
2023-12-20 10:58:06.728 JST - Started function - query_string: {'unix_sock': '/cloudsql/nownow-8907a:asia-northeast3:myinstance2/.s.PGSQL.5432'}2023-12-20 10:58:09.054 JST - Created engineError: (pg8000.core.InterfaceError) ('communication error', FileNotFoundError(2, 'No such file or directory'))(Background on this error at: http://sqlalche.me/e/rvf5)
Here's what I ran in Cloud Shell when setting up the database:
$ gcloud sql connect myinstance2 --user=postgresAllowlisting your IP for incoming connection for 5 minutes...done. Connecting to database with SQL user [postgres].Password: # typed in redactedpsql (16.1 (Debian 16.1-1.pgdg110+1), server 15.4)SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)Type "help" for help.postgres=> CREATE DATABASE guestbook;\CREATE DATABASEpostgres=> \connect guestbook;Password: # typed in redactedpsql (16.1 (Debian 16.1-1.pgdg110+1), server 15.4)SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off)You are now connected to database "guestbook" as user "postgres".guestbook=> CREATE TABLE entries (guestName VARCHAR(255), content VARCHAR(255), entryID SERIAL PRIMARY KEY);CREATE TABLE
How can I get this to work? I feel like I've checked everything:
- The function is run with a service account that has the Cloud SQL Client role
- redacted is the password for both postgres itself and the database (I am able to connect using it via Cloud Shell)
- The PostgreSQL instance has both Public IP and Private IP with "private path" enabled
- The SQL > Connections > Security has Google Cloud services authorization and App Engine authorization "Enabled", and "Allow only SSL connections" and "Require trusted client certificates" set to "Disabled"
Another interesting anomoly with the cloud function is I verified 3 times during creation that "Allow unauthenticated invocations" was selected, but after creating the function it went back to "Require authentication". I don't think this is super relevant though, since I'm still able to run the function, I just can't connect to the database.