将App Engine&Flask&SQLAlChemy连接到Cloud SQL [英] Connect App Engine & Flask & SQLAlchemy to Cloud Sql

查看:25
本文介绍了将App Engine&Flask&SQLAlChemy连接到Cloud SQL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在将使用Flaskand SQLAlChemy创建的网站部署到Google App Engine时遇到了问题。在本地运行时,我的Web应用可以成功连接到我的云SQL,但在部署tp App Engine时,它就是不能。日志资源管理器中记录的错误如下所示。

sqlalchemy.exc.OperationalError: (MySQLdb._exceptions.OperationalError) (2003, "Can't connect to MySQL server on 'my sql instance ip address' (110)")"

这基本上说明不了什么。我想问题可能是我的本地计算机被列入了SQL实例的白名单。但我的App Engine应用程序(与SQL实例位于同一项目中)也应该自动被列入白名单,对吗?

在我的FlaskApp配置中,我有以下内容:

"""Flask configuration."""
from os import environ, path
import os
from dotenv import load_dotenv

basedir = path.abspath(path.dirname(__file__))
load_dotenv(path.join(basedir, '.env'))

CLOUD_SQL_USERNAME = environ.get('CLOUD_SQL_USERNAME')
CLOUD_SQL_PASSWORD = environ.get('CLOUD_SQL_PASSWORD')
SQL_PUBLIC_IP_ADDRESS = environ.get('SQL_PUBLIC_IP_ADDRESS')
CLOUD_SQL_PORT = environ.get('CLOUD_SQL_PORT')
CLOUD_SQL_DATABASE_NAME = environ.get('CLOUD_SQL_DATABASE_NAME')
PROJECT_ID = environ.get('PROJECT_ID')
SQL_INSTANCE_NAME = environ.get('SQL_INSTANCE_NAME')
MAPBOX_TOKEN = environ.get('MAPBOX_TOKEN')
CLOUD_SQL_CONNECTION_NAME = environ.get('CLOUD_SQL_CONNECTION_NAME')

def gen_connection_string():
    # if not on Google then use normal connection
    if not os.getenv('SERVER_SOFTWARE', '').startswith('Google App Engine/'):
        return f"mysql+mysqldb://{CLOUD_SQL_USERNAME}:{CLOUD_SQL_PASSWORD}@{SQL_PUBLIC_IP_ADDRESS}:{CLOUD_SQL_PORT}/{CLOUD_SQL_DATABASE_NAME}?unix_socket=/cloudsql/{PROJECT_ID}:{SQL_INSTANCE_NAME}"
    else:
        return f'mysql+mysqldb://{CLOUD_SQL_USERNAME}:{CLOUD_SQL_PASSWORD}/{SQL_INSTANCE_NAME}?unix_socket=/cloudsql/{CLOUD_SQL_CONNECTION_NAME}'

class Config:
    """Base config."""
    SECRET_KEY = environ.get('SECRET_KEY')
    STATIC_FOLDER = 'static'
    TEMPLATES_FOLDER = 'templates'
    SQLALCHEMY_DATABASE_URI = gen_connection_string()
    SQLALCHEMY_TRACK_MODIFICATIONS = True

class ProdConfig(Config):
    FLASK_ENV = 'production'
    DEBUG = False
    TESTING = False

class DevConfig(Config):
    FLASK_ENV = 'development'
    DEBUG = True
    TESTING = True

这在本地运行时效果很好,但在实际部署时并非如此。

我有点迷茫,因为我只是一个16岁的新手,App Engine对我来说太复杂了。如有任何帮助,我将不胜感激:)

编辑: 这是我当前的app.yaml文件:

runtime: python38
entrypoint: python main.py

handlers:
  # This configures Google App Engine to serve the files in the app's static
  # directory.
- url: /static
  secure: always
  static_dir: static

  # This handler routes all requests not caught above to your main app. It is
  # required when static routes are defined, but can be omitted (along with
  # the entire handlers section) when there are no static files defined.
- url: /.*
  secure: always
  script: auto

我尝试将环境变量添加到app.yaml文件中,但没有成功。仍然失败。

推荐答案

我是谷歌Cloud SQL开发人员关系团队的工程师。

我在日志中看到的第一个问题是,App Engine尝试使用公共IP地址而不是Unix套接字进行连接,因此它尝试使用第一个连接字符串而不是第二个连接字符串。因此,我怀疑检查SERVER_SOFTWARE环境变量的值不会以您预期的方式工作。Python 3 App Engine runtime的文档建议使用

if os.getenv('GAE_ENV', '').startswith('standard'):
您需要确保您的App Engine服务帐户具有Cloud SQL Client权限。有有关如何执行此操作的信息here

另外,官方推荐使用Cloud SQL Auth Proxy或新发布的Cloud SQL Python Connector连接云SQL。这两个选项都将允许您轻松连接,而不必将您的IP地址添加到允许列表,并且本地和部署的数据库连接参数应该相同。

附注:作为一个16岁的新手,你使用App Engine真的很酷。即使对我们这些已经做了一段时间的人来说,这些东西也是棘手的。:)

这篇关于将App Engine&Flask&SQLAlChemy连接到Cloud SQL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆