使用 Python 3、Flask、SQLAlchemy、psycopg2-binary 包和 CloudSQL Postgres 在 Google App Engine 上运行一个小的 Web 应用程序(灵活)。 该应用程序在我的本地开发环境中正确连接到 CloudSQL(我使用代理),但在云中部署时似乎无法连接。
上周我第一次部署它时工作正常。 推送更新并重新部署后,应用程序不再连接到云外壳中的 CloudSQL,或者在部署时 - 即使在回滚到之前的提交之后也是如此。 但它使用代理在我的本地开发计算机上连接得很好。
我已经通过调试验证了必要的凭据是否已正确插入到我的SQLALCHEMY_DATABASE_URI中,即:postgres+psycopg2://[user]:[pw]@/[db_name]?host=/cloudsql/breadsheet:us-west1:breadsheet
.
自初始部署以来,我在平台上所做的唯一更改是从云数据存储升级到 Firestore,这是我从中提取环境变量以构建 URI 的地方。 没有数据来自数据存储,所以这无关紧要。
我正在遵循 Unix 的 GAE Postgres 连接指南。 这是我的应用程序.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 进行硬编码
- 使用 nano 在我的 app.yaml 中对
env_variables
下的SQLALCHEMY_DATABASE_URI进行硬编码
接下来要尝试什么?
对于那些将来通过搜索阅读本文的人,我之前跳过了export SQLALCHEMY_DATABASE_URI=postgresql+psycopg2://[USER]:[PW]@127.0.0.1:5432/[DB_NAME]
,因为我并不特别关心Cloud shell环境,并认为它不会对部署产生影响。 显然确实如此。
后来,在对 cloud shell 中的数据库连接进行故障排除时,我发现自己跳过了这个两步命令的第一部分 (sudo mkdir /cloudsql;
sudo mkdir /cloudsql; sudo chmod 777 /cloudsql
因为我已经创建了/cloudsql 文件夹。 我仍然不确定为什么需要命令的两个部分 - 特别是当文件夹已经存在时 - 但是如果没有它们,db 连接对我不起作用。
还有一点说明:在app.yaml 中env_variables:
下设置SQLALCHEMY_DATABASE_URI
不是必需的,前提是您在应用程序的其他位置设置了该值。 添加到env_variables:
只是使值可用作易于访问的变量。