Cloud Run部署Flask应用连接Cloud SQL遇权限拒绝及mydb未定义问题
问题1:
mydb is not defined 错误修复 问题原因
mydb 变量仅在 if __name__ == "__main__" 代码块中定义,而Cloud Run部署Flask应用时,会通过WSGI服务器(如gunicorn)启动,不会执行这个本地运行入口块,导致路由函数无法找到该变量。
解决方案
将数据库连接池初始化逻辑移到全局作用域,并在路由中通过连接池动态获取连接(避免全局连接因超时/断开失效):
from flask import Flask from google.cloud.sql.connector import Connector, IPTypes import sqlalchemy app = Flask(__name__) # 全局声明连接池变量 pool = None def createSQLConnection(): connector = Connector() # 定义动态获取连接的函数,每次调用都会创建新的有效连接 def get_conn(): return connector.connect( "actual_region", "pymysql", user="root", password="actual_password", db="actual_db", ip_type=IPTypes.PUBLIC ) # 创建连接池,依赖动态获取连接的函数 pool = sqlalchemy.create_engine( "mysql+pymysql://", creator=get_conn, ) return pool # 应用首次请求前初始化连接池 @app.before_first_request def init_db(): global pool pool = createSQLConnection() @app.route('/') def index(): # 从连接池临时获取连接,使用后自动归还 with pool.connect() as mydb: result = mydb.execute(sqlalchemy.text("SELECT * from users")).fetchall() msg = "" for row in result: msg += str(row) + "\n" return msg if __name__ == "__main__": pool = createSQLConnection() app.run(debug=True)
问题2:
Access denied for user 'root'@'ACTUAL_IP_ADDRESS' 错误修复 问题原因
- 原代码中
Connector在with块内创建的连接,会随块结束被关闭,导致连接池返回无效连接,触发认证错误。 - Cloud Run服务账户权限未正确生效,或Cloud SQL的root用户未授权从任意主机访问。
解决方案
- 按上述代码调整连接池创建逻辑,确保每次获取的都是Connector生成的有效连接。
- 检查Cloud SQL的root用户权限:
在SQL Workbench中执行以下命令,确保root允许从任意主机访问:SELECT host FROM mysql.user WHERE user='root'; -- 如果结果不是%,执行以下命令 ALTER USER 'root'@'%' IDENTIFIED BY 'your_password'; FLUSH PRIVILEGES; - 确认Cloud Run服务账户权限:
找到Cloud Run服务使用的默认服务账户(格式为PROJECT_NUMBER-compute@developer.gserviceaccount.com),确保该账户被授予Cloud SQL Client角色(roles/cloudsql.client)。
额外注意事项
- 容器化时,
requirements.txt必须包含所有依赖包:flask google-cloud-sql-connector sqlalchemy pymysql - Cloud Run部署时,务必关联目标Cloud SQL实例:
控制台部署时在"Connections"中选择对应实例;命令行部署添加参数:--add-cloudsql-instances=PROJECT_ID:REGION:INSTANCE_NAME
内容的提问来源于stack exchange,提问作者DarkMaster964
相关产品推荐
相关产品推荐

