【问题标题】:Unable to connect Google App Engine to CloudSQL Postgres (via SQLAlchemy) in cloud shell无法在 Cloud Shell 中将 Google App Engine 连接到 CloudSQL Postgres(通过 SQLAlchemy)
【发布时间】:2019-04-07 18:03:50
【问题描述】:

使用 Python 3、Flask、SQLAlchemy、psycopg2-binary 包和 CloudSQL Postgres 在 Google App Engine(灵活)上运行小型网络应用。该应用在我的本地开发环境中正确连接到 CloudSQL(我使用代理),但在部署在云中时似乎无法连接。

上周我第一次部署它时运行良好。在推送更新并重新部署后,应用程序不再连接到云外壳中的 CloudSQL 或在部署时 - 即使在回滚到之前的提交后也是如此。但它使用代理在我的本地开发机器上连接得很好。

我已经通过调试验证了必要的凭据已正确插入到我的 SQLALCHEMY_DATABASE_URI 中,即:postgres+psycopg2://[user]:[pw]@/[db_name]?host=/cloudsql/breadsheet:us-west1:breadsheet

自初始部署以来我在平台上所做的唯一更改是从 Cloud Datastore 升级到 Firestore,这是我从中提取环境变量以构建 URI 的地方。没有数据来自 Datastore,所以这无关紧要。

我正在关注 Unix 的 GAE Postgres connection guide。这是我的 app.yaml:

runtime: python
env: flex

instance_class: F1

entrypoint: gunicorn -w 1 breadsheet:breadapp

error_handlers:
  - file: app/templates/errors/default_error.html

  - error_code: over_quota
    file: app/templates/errors/over_quota.html

beta_settings:
  cloud_sql_instances: breadsheet:us-west1:breadsheet

这是我从云外壳运行 gunicorn 时的错误:

(venv) [me]@cloudshell:~/breadsheet (breadsheet)$ gunicorn -w 1 breadsheet:breadapp
[2019-04-07 10:23:16 -0700] [471] [INFO] Starting gunicorn 19.9.0
[2019-04-07 10:23:16 -0700] [471] [INFO] Listening at: http://127.0.0.1:8000 (471)
[2019-04-07 10:23:16 -0700] [471] [INFO] Using worker: sync
[2019-04-07 10:23:16 -0700] [474] [INFO] Booting worker with pid: 474
2019-04-07 09:40:08,838 Exception on / [GET]
Traceback (most recent call last):
[...]
  File "/home/[me]/breadsheet/venv/lib/python3.5/site-packages/sqlalchemy/engine/default.py", line 437, in connect
    return self.dbapi.connect(*cargs, **cparams)
  File "/home/[me]/breadsheet/venv/lib/python3.5/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
psycopg2.OperationalError: could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/cloudsql/breadsheet:us-west1:breadsheet/.s.PGSQL.5432"?


The above exception was the direct cause of the following exception:
[line of code with the first database call in my app]
[...]
  File "/home/[me]/breadsheet/venv/lib/python3.5/site-packages/psycopg2/__init__.py", line 130, in connect
    conn = _connect(dsn, connection_factory=connection_factory, **kwasync)
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: No such file or directory
        Is the server running locally and accepting
        connections on Unix domain socket "/cloudsql/breadsheet:us-west1:breadsheet/.s.PGSQL.5432"?

尝试了以下(以及更多!)但无济于事:

  • 在 CloudSQL 管理中将各种 IP 列入白名单
  • 调整 IAM 权限
  • 使用 nano 注释掉 Firestore 代码并对 URI 进行硬编码
  • 在我的 app.yaml 中使用 nano 对 env_variables 下的 SQLALCHEMY_DATABASE_URI 进行硬编码

接下来要尝试什么?

【问题讨论】:

  • SQLALCHEMY_DATABASE_URI 中不应该有 'unix_socket' 而不是 'host' 吗?
  • 您可以尝试强制使用以下引擎进行连接吗?:'ENGINE': 'django.db.backends.postgresql_psycopg2'
  • 尝试使用 'unix_socket' 和 'unix_sock' 得到以下结果:psycopg2.ProgrammingError: invalid dsn: invalid connection option "unix_socket"
  • 再次按照该指南进行操作-这次是T-并且成功了。谢谢!对于将来通过搜索阅读本文的人,我之前跳过了export SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://[USER]:[PW]@127.0.0.1:5432/[DB_NAME],因为我并不特别关心云外壳环境,并认为它不会对部署产生影响。 (顺便说一句:不需要在 app.yaml 中的 env_variables: 下设置 SQLALCHEMY_DATABASE_URI,前提是您在代码中的其他位置设置了该值。我将我的 app 和 db 密钥存储在 Firestore 中并通过代码构建它们。)
  • 后人的另一条评论。后来,在对 cloud shell 中的 db 连接进行故障排除时,我发现自己跳过了 sudo mkdir /cloudsql; sudo chmod 777 /cloudsql 命令,因为我已经创建了 /cloudsql 文件夹——忽略了该命令的第二部分。没有sudo chmod 777 /cloudsql 命令,数据库连接将无法工作:)

标签: python google-app-engine sqlalchemy google-cloud-sql


【解决方案1】:

对于那些以后通过搜索阅读本文的人,我之前跳过了export SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://[USER]:[PW]@127.0.0.1:5432/[DB_NAME],因为我并不特别关心云外壳环境,并认为它不会对部署产生影响。显然是的。

后来,在对 cloud shell 中的 db 连接进行故障排除时,我发现自己跳过了这个两步命令 sudo mkdir /cloudsql; sudo chmod 777 /cloudsql 的第一部分 (sudo mkdir /cloudsql;),因为我已经创建了 /cloudsql 文件夹。我仍然不确定为什么需要命令的两个部分——尤其是当文件夹已经存在时——但是如果没有这两个部分,数据库连接对我不起作用。

还有一点需要注意:在 app.yaml 中将 SQLALCHEMY_DATABASE_URI 设置在 env_variables: 下是不需要的,前提是您在应用程序的其他位置设置了该值。添加到 env_variables: 只会使值作为易于访问的变量提供。

【讨论】:

    猜你喜欢
    • 2020-06-07
    • 2017-08-07
    • 2021-08-04
    • 2017-12-05
    • 1970-01-01
    • 2015-12-18
    • 2017-08-28
    • 2020-10-18
    • 1970-01-01
    相关资源
    最近更新 更多