首页 > 解决方案 > 无法在 Google App Engine 中使用 PostgreSQL 部署 Flask-Python 应用程序

问题描述

尝试将 Flask-Python 代码部署到 Google App Engine 时出现错误。我使用 PostgreSQL 作为我的数据库。这是错误:

Traceback (most recent call last):
  File "/env/lib/python3.6/site-packages/gunicorn/arbiter.py", line 557, in spawn_worker
    worker.init_process()
  File "/env/lib/python3.6/site-packages/gunicorn/workers/base.py", line 126, in init_process
    self.load_wsgi()
  File "/env/lib/python3.6/site-packages/gunicorn/workers/base.py", line 136, in load_wsgi
    self.wsgi = self.app.wsgi()
  File "/env/lib/python3.6/site-packages/gunicorn/app/base.py", line 67, in wsgi
    self.callable = self.load()
  File "/env/lib/python3.6/site-packages/gunicorn/app/wsgiapp.py", line 65, in load
    return self.load_wsgiapp()
  File "/env/lib/python3.6/site-packages/gunicorn/app/wsgiapp.py", line 52, in load_wsgiapp
    return util.import_app(self.app_uri)
  File "/env/lib/python3.6/site-packages/gunicorn/util.py", line 357, in import_app
    __import__(module)
  File "/home/vmagent/app/main.py", line 20, in <module>
    SQLAlchemy.engine.url.URL(
AttributeError: 'property' object has no attribute 'url'
[2021-01-03 14:35:46 +0000] [8] [INFO] Worker exiting (pid: 8)
[2021-01-03 14:35:46 +0000] [1] [INFO] Shutting down: Master
[2021-01-03 14:35:46 +0000] [1] [INFO] Reason: Worker failed to boot.

main.py 代码:

from flask import Flask, redirect, url_for, render_template, request, 
from flask_sqlalchemy import SQLAlchemy
import os


# Remember - storing secrets in plaintext is potentially unsafe. Consider using
# something like https://cloud.google.com/secret-manager/docs/overview to help keep
# secrets secret.
db_user = os.environ["DB_USER"]
db_pass = os.environ["DB_PASS"]
db_name = os.environ["DB_NAME"]
db_socket_dir = os.environ.get("DB_SOCKET_DIR", "/cloudsql")
cloud_sql_connection_name = os.environ["CLOUD_SQL_CONNECTION_NAME"]

pool = SQLAlchemy.create_engine(

    # Equivalent URL:
    # postgres+pg8000://<db_user>:<db_pass>@/<db_name>
    #                         ?unix_sock=<socket_path>/<cloud_sql_instance_name>/.s.PGSQL.5432
    SQLAlchemy.engine.url.URL(
        drivername="postgresql+pg8000",
        username=db_user,  # e.g. "my-database-user"
        password=db_pass,  # e.g. "my-database-password"
        database=db_name,  # e.g. "my-database-name"
        query={
            "unix_sock": "{}/{}/.s.PGSQL.5432".format(
                db_socket_dir,  # e.g. "/cloudsql"
                cloud_sql_connection_name)  # i.e "<PROJECT-NAME>:<INSTANCE-REGION>:<INSTANCE-NAME>"
        }
    ),
    **db_config
)

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres+psycopg2://postgres:<password>@<public ip>/flaskapp?host=/cloudsql/<instance name>'
app.debug = True
db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), unique=True)
    age = db.Column(db.String(120), unique=True)
   

    def __init__(self, name, age):
        self.name = name
        self.age = age
        

    def __repr__(self):
        return '<User %r>' % self.username



@app.route("/")
def home():
    return render_template("home.html")



@app.route('/form')
def form():
    title ="form"
    return render_template("form.html", title=title)




@app.route('/success', methods=["POST"])
def success():
    if request.method == 'POST':
        user = User(request.form['name'],request.form['age'])

        
        try:
            db.session.add(user)
            db.session.commit()
            return render_template("success.html")

        except:
            return render_template('form.html')
    else:
        return redirect('/')




db.create_all()

if __name__ == "__main__":
    app.run(host="127.0.0.1",port=8080, debug=True) 

app.yaml 代码:

entrypoint: "gunicorn -b:$PORT main:app"
env: flex
runtime: python
runtime_config: 
  python_version: 3

env_variables:
  DB_USER: postgres
  DB_PASS: <password>
  DB_NAME: flaskapp
  DB_SOCKET_DIR: /cloudsql
  CLOUD_SQL_CONNECTION_NAME: <instance name>
beta_settings:
  cloud_sql_instances: <instance name>

requirements.txt 代码:

click==7.1.2
Flask==1.1.2
Flask-SQLAlchemy==2.4.4
itsdangerous==1.1.0
Jinja2==2.11.2
MarkupSafe==1.1.1
psycopg2==2.8.6
SQLAlchemy==1.3.22
Werkzeug==1.0.1
gunicorn==19.6.0

这是我在部署应用程序之前使用的指南:https ://cloud.google.com/sql/docs/postgres/connect-app-engine-standard 。根据该指南,我启用了 API,安装了云 SDK,并为 PostgreSQL 创建了一个 SQL 实例。

我究竟做错了什么?您的帮助将不胜感激。

标签: pythonpostgresqlgoogle-app-enginegoogle-cloud-platformflask-sqlalchemy

解决方案


我检查了您的问题,发现该教程是关于从 App Engine Standard 连接到 Cloud SQL。但是你的app.yaml文件有env: flex. 因此,您应该决定要从哪个产品连接到 Cloud SQL。

我写了一个教程:“使用 TCP 和 UNIX 域套接字 2020 从应用程序引擎(灵活和标准)连接到云 SQL”

如果您尝试从 App Engine Flex 进行连接,请不要忘记在您的app.yaml:

启用 Unix 域套接字

beta_settings:
  cloud_sql_instances: INSTANCE_CONNECTION_NAME

从 App Engine 柔性环境连接到 Cloud SQL


推荐阅读