如何从Cloud Functions连接到Google Cloud PostgreSQL数据库?

9wbgstp7  于 12个月前  发布在  PostgreSQL
关注(0)|答案(2)|浏览(138)

我正在学习Connecting to Cloud SQL with Cloud Functions教程,但我的Cloud Function无法连接到PostgreSQL数据库
下面是我的函数代码:

import sqlalchemy

connection_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'

字符串
当我从“测试”选项卡运行它时,我得到:

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 engine
Error: (pg8000.core.InterfaceError) ('communication error', FileNotFoundError(2, 'No such file or directory'))
(Background on this error at: http://sqlalche.me/e/rvf5)


以下是我在设置数据库时在Cloud Shell中运行的内容:

$ gcloud sql connect myinstance2 --user=postgres
Allowlisting your IP for incoming connection for 5 minutes...done.                                                                                                                                      
Connecting to database with SQL user [postgres].Password: # typed in redacted
psql (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 DATABASE
postgres=> \connect guestbook;
Password: # typed in redacted
psql (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


我怎么才能让它工作呢?我觉得我已经检查了所有的东西:

  • 该函数使用具有Cloud SQL Client角色的服务帐户运行
  • redacted是postgres本身和数据库的密码(我可以通过Cloud Shell使用它进行连接)
  • PostgreSQL示例同时具有公网IP和私有IP,并启用了“私有路径”
  • SQL > Connections > Security将Google Cloud Services授权和App Engine授权设置为“Enabled”,并将“Allow only SSL connections”和“Require trusted client certificates”设置为“Disabled”。

云函数的另一个有趣的异常是,我在创建过程中验证了3次“允许未经身份验证的调用”被选中,但在创建函数后,它又回到了“需要身份验证”。我不认为这是超级相关的,因为我仍然能够 * 运行 * 函数,我只是不能连接到数据库。

xdyibdwo

xdyibdwo1#

我建议使用Cloud SQL Python Connector库。它将管理与安全TLS/SSL连接的连接,并给予您使用automatic IAM authentication的能力,沿着其他好处。它还允许您选择连接到哪个IP类型(公共还是私有),因为上面的unix套接字没有明确说明这一点。
它还允许您连接,而无需执行您提到的额外步骤:
在Container(s)选项卡中,找到连接名称并将其添加到Cloud SQL连接
云函数的示例如下所示:

from google.cloud.sql.connector import Connector, IPTypes
import sqlalchemy
import requests

connector = None
db = None

def init_pool(connector):
  def getconn():
    connection = connector.connect(
      "<YOUR_PROJECT>:<YOUR_REGION>:<YOUR_INSTANCE_NAME>",
      "pg8000",
      user="<YOUR_USER>",
      password="<YOUR_PASSWORD>",
      db="<YOUR_DB>",
      ip_type=IPTypes.PUBLIC,  #IPTypes.PRIVATE for Private IP
    )
    return connection

  # create connection pool
  engine = sqlalchemy.create_engine("postgresql+pg8000://", creator=getconn)
  return engine

def hello_world(request):
  global connector, db
  if not db:
    connector = Connector()
    db = init_pool(connector)
  # build connection for db using Python Connector
  with db.connect() as conn:
    result = conn.execute(sqlalchemy.text("SELECT NOW()")).fetchone()
  print("Successfully connected to Cloud SQL instance!")
  return str(result[0])

字符串
我们延迟初始化连接池的原因是它可以跨多个请求使用(描述中的代码为每个请求创建一个新的连接池)。

jmp7cifd

jmp7cifd2#

奇怪的是,这并不是我遵循的Collab的一部分,但你也需要遵循以下步骤:https://cloud.google.com/sql/docs/mysql/connect-functions#configure
您需要仔细遵循该页面(以防它发生变化),但一般步骤是:

  • 转到Cloud Run页面
  • 转到,然后编辑函数
  • 在Container(s)选项卡中,找到连接名称并将其添加到Cloud SQL连接

部署这些更改后,您的函数现在将能够连接到SQL数据库

相关问题