Flask应用MySQL连接报错2003:无法连接localhost(111)求助
看起来你遇到的是远程MySQL数据库(这里是Heroku的ClearDB)连接失败的问题,结合你给出的信息,我来一步步帮你排查:
首先明确核心问题
你提到注释了bind-address但没用,这是因为你连接的是托管在Heroku的ClearDB远程数据库,bind-address是MySQL服务器端的配置,你自己本地的MySQL配置不影响远程连接——而且ClearDB的服务器配置你也无权修改,所以这一步其实对解决问题没帮助。
而ping服务器无响应,说明网络层面就没打通,再结合你的代码,大概率是配置参数没正确加载或者网络/权限限制导致的。
具体排查步骤
1. 先修正代码里的环境变量获取逻辑
你的代码里写了:
DATABASE_HOST=os.environ.get('****.cleardb.com'),
这里有个明显的问题:os.environ.get()的参数应该是环境变量的名称,而不是具体的数据库地址字符串!比如Heroku的ClearDB会自动给你的应用设置CLEARDB_DATABASE_URL这个环境变量,你需要解析这个URL来获取host、user等参数,而不是直接写地址作为环境变量名。
正确的做法应该是解析这个URL:
import os from urllib.parse import urlparse def create_app(): app = Flask(__name__) # 从环境变量获取ClearDB的完整数据库URL clear_db_url = os.environ.get('CLEARDB_DATABASE_URL') if clear_db_url: # 解析URL提取各个参数 url_components = urlparse(clear_db_url) app.config.from_mapping( SECRET_KEY = "***", DATABASE_HOST=url_components.hostname, DATABASE_PASSWORD=url_components.password, DATABASE_USER=url_components.username, DATABASE=url_components.path.lstrip('/'), # 去掉路径开头的斜杠 ) # 其他代码...
如果是本地测试,你可以手动设置环境变量,或者临时在代码里填入正确的ClearDB参数(注意别把敏感信息提交到代码仓库)。
2. 验证MySQL端口的网络连通性
ping不通服务器不代表MySQL端口无法访问(有些服务器会禁用ping响应),你应该直接测试MySQL的默认端口3306:
- 用telnet命令:
telnet your-cleardb-host.cleardb.com 3306 - 或者用nc命令(如果安装了的话):
nc -zv your-cleardb-host.cleardb.com 3306
如果这些命令也无法连接,说明:
- 你的本地防火墙或路由器拦截了3306端口的出站请求,尝试关闭防火墙或者换个网络(比如手机热点)测试
- 你的公网IP不在ClearDB的访问白名单里:登录Heroku控制台,找到ClearDB插件,进入管理界面,在Access Control里添加你的公网IP(可以通过搜索引擎查询自己的公网IP)
3. 确认ClearDB的配置正确性
登录Heroku的应用控制台,查看ClearDB的配置参数是否正确:
- 检查
CLEARDB_DATABASE_URL的格式是否正确:mysql://user:password@host/database_name - 确保没有拼写错误,比如用户名、密码、主机地址是否和ClearDB管理界面里的一致
总结
最可能的原因是你代码里的环境变量获取方式错误,导致实际尝试连接的是localhost(因为os.environ.get('****.cleardb.com')返回None,Flask可能默认用localhost),再加上网络层面的限制,所以出现了2003错误。先修正环境变量的解析方式,再排查网络和白名单问题,应该就能解决了。
内容的提问来源于stack exchange,提问作者Franco

