将 App Engine & Flask & SQLAlchemy 连接到云端 Sql
Connect App Engine & Flask & SQLAlchemy to Cloud Sql
我在将使用 Flask 和 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 实例位于同一个项目中)也应该自动列入白名单,对吗?
在我的 Flask App 配置中,我有以下内容:
"""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 文件,但没有成功。还是失败了。
我是云 SQL 开发人员关系团队的一名工程师 Google。
我在日志中看到的第一个问题是 App Engine 正在尝试使用 public IP 地址而不是 Unix 套接字进行连接,因此它正在尝试使用第一个连接字符串而不是第二个.所以我怀疑检查 SERVER_SOFTWARE
环境变量的值没有按照您预期的方式工作。 Python 3 App Engine runtime 的文档建议使用
if os.getenv('GAE_ENV', '').startswith('standard'):
您需要确保您的 App Engine 服务帐户具有 Cloud SQL Client
权限。有关于如何做到这一点的信息 here。
此外,官方推荐的连接云 SQL 的方法是使用 Cloud SQL Auth Proxy, or the newly released Cloud SQL Python Connector。这两个选项都允许您轻松连接,而无需将您的 IP 地址添加到白名单,并且本地和部署的数据库连接参数应该相同。
P.S。作为一个 16 岁的新手使用 App Engine 真是太棒了。即使对我们这些已经做了一段时间的人来说,这些东西也很棘手。 :)
我在将使用 Flask 和 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 实例位于同一个项目中)也应该自动列入白名单,对吗?
在我的 Flask App 配置中,我有以下内容:
"""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 文件,但没有成功。还是失败了。
我是云 SQL 开发人员关系团队的一名工程师 Google。
我在日志中看到的第一个问题是 App Engine 正在尝试使用 public IP 地址而不是 Unix 套接字进行连接,因此它正在尝试使用第一个连接字符串而不是第二个.所以我怀疑检查 SERVER_SOFTWARE
环境变量的值没有按照您预期的方式工作。 Python 3 App Engine runtime 的文档建议使用
if os.getenv('GAE_ENV', '').startswith('standard'):
您需要确保您的 App Engine 服务帐户具有 Cloud SQL Client
权限。有关于如何做到这一点的信息 here。
此外,官方推荐的连接云 SQL 的方法是使用 Cloud SQL Auth Proxy, or the newly released Cloud SQL Python Connector。这两个选项都允许您轻松连接,而无需将您的 IP 地址添加到白名单,并且本地和部署的数据库连接参数应该相同。
P.S。作为一个 16 岁的新手使用 App Engine 真是太棒了。即使对我们这些已经做了一段时间的人来说,这些东西也很棘手。 :)