Flask从SQLite迁移MySQL连接失败:可通过Datagrip连接但应用无法连接
错误信息
sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "无法连接到位于'localhost'的MySQL服务器 ([Errno 111] 连接被拒绝)")
问题背景
将Flask应用的数据库从SQLite切换为MySQL时连接失败,但可通过Datagrip正常登录该数据库,核心代码如下:
from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate app = Flask(__name__) app_context = app.app_context() app_context.push() # app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///db.sqlite" app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:pass@localhost:3306/horizon_db' app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False app.config["SECRET_KEY"] = "abc" app.config['ENV'] = 'development' app.config['DEBUG'] = True app.config['TESTING'] = True db = SQLAlchemy(app) migrate = Migrate(app, db)
排查与解决步骤
替换localhost为127.0.0.1
部分系统中localhost会优先解析到IPv6地址::1,但MySQL默认可能只监听IPv4的127.0.0.1。Datagrip可能自动适配了IPv4连接,而Flask使用的连接字符串未指定。修改连接字符串为:app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:pass@127.0.0.1:3306/horizon_db'检查MySQL用户权限
MySQL中root@localhost和root@127.0.0.1是两个独立的用户,权限范围不同。如果Datagrip使用的是本地套接字连接(对应root@localhost),而Flask使用TCP连接(对应root@127.0.0.1),则需要为后者分配权限:
登录MySQL执行以下命令:GRANT ALL PRIVILEGES ON horizon_db.* TO 'root'@'127.0.0.1' IDENTIFIED BY '你的密码'; FLUSH PRIVILEGES;确认MySQL服务监听配置
检查MySQL配置文件(my.cnf或my.ini)中的bind-address参数,确保其设置为127.0.0.1(仅允许本地连接)或0.0.0.0(允许远程连接),同时确认port参数为3306。
可通过以下命令查看监听状态:netstat -tulpn | grep 3306输出需包含
127.0.0.1:3306或0.0.0.0:3306。验证pymysql依赖安装
连接字符串使用了mysql+pymysql驱动,需确保已安装该依赖:pip install pymysql确认目标数据库存在
检查horizon_db数据库是否已创建,登录MySQL执行:SHOW DATABASES LIKE 'horizon_db';若不存在,执行以下命令创建:
CREATE DATABASE horizon_db;
内容的提问来源于stack exchange,提问作者Daevid The Great

