【发布时间】: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