V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
yuting0501
V2EX  ›  Python

请教一下 flask+sqlalchemy+mysql 连接错误问题

  •  
  •   yuting0501 · 2019-05-06 22:56:47 +08:00 · 3690 次点击
    这是一个创建于 2032 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在本地调试 docker-compose 调试 mysql+nginx+flask 程序,报错(2003, "Can't connect to MySQL server on '127.0.0.1' ([Errno 111] Connection refused)")

    线索如下:

    • Flask app 运行地址: 0.0.0.0:5000
    • 已将 mysql.cnf 中的bind-address改为0.0.0.0,并在容器里面确认过更改成功
    • 使用 MySQLWorkbench 可以成功连接到 localhost 数据库
    • SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:[email protected]:3306/my_database?charset=utf8'

    期待回复,非常感谢!

    完整的错误日志:

    webapp_1  | The above exception was the direct cause of the following exception:
    webapp_1  | 
    webapp_1  | Traceback (most recent call last):
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/gunicorn/workers/sync.py", line 135, in handle
    webapp_1  |     self.handle_request(listener, req, client, addr)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/gunicorn/workers/sync.py", line 176, in handle_request
    webapp_1  |     respiter = self.wsgi(environ, resp.start_response)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1997, in __call__
    webapp_1  |     return self.wsgi_app(environ, start_response)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1985, in wsgi_app
    webapp_1  |     response = self.handle_exception(e)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1540, in handle_exception
    webapp_1  |     reraise(exc_type, exc_value, tb)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    webapp_1  |     raise value
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1982, in wsgi_app
    webapp_1  |     response = self.full_dispatch_request()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1614, in full_dispatch_request
    webapp_1  |     rv = self.handle_user_exception(e)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1517, in handle_user_exception
    webapp_1  |     reraise(exc_type, exc_value, tb)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/_compat.py", line 33, in reraise
    webapp_1  |     raise value
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1612, in full_dispatch_request
    webapp_1  |     rv = self.dispatch_request()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask/app.py", line 1598, in dispatch_request
    webapp_1  |     return self.view_functions[rule.endpoint](**req.view_args)
    webapp_1  |   File "/iodock/app/auth/views.py", line 58, in register
    webapp_1  |     if form.validate_on_submit():
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/flask_wtf/form.py", line 101, in validate_on_submit
    webapp_1  |     return self.is_submitted() and self.validate()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/wtforms/form.py", line 310, in validate
    webapp_1  |     return super(Form, self).validate(extra)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/wtforms/form.py", line 152, in validate
    webapp_1  |     if not field.validate(self, extra):
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/wtforms/fields/core.py", line 204, in validate
    webapp_1  |     stop_validation = self._run_validation_chain(form, chain)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/wtforms/fields/core.py", line 224, in _run_validation_chain
    webapp_1  |     validator(form, self)
    webapp_1  |   File "/iodock/app/auth/forms.py", line 31, in validate_email
    webapp_1  |     if UserBaseInfo.query.filter_by(email=field.data).first():
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2755, in first
    webapp_1  |     ret = list(self[0:1])
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2547, in __getitem__
    webapp_1  |     return list(res)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2855, in __iter__
    webapp_1  |     return self._execute_and_instances(context)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2876, in _execute_and_instances
    webapp_1  |     close_with_result=True)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2885, in _get_bind_args
    webapp_1  |     **kw
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/query.py", line 2867, in _connection_from_session
    webapp_1  |     conn = self.session.connection(**kw)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 998, in connection
    webapp_1  |     execution_options=execution_options)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 1003, in _connection_for_bind
    webapp_1  |     engine, execution_options)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/orm/session.py", line 403, in _connection_for_bind
    webapp_1  |     conn = bind.contextual_connect()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2112, in contextual_connect
    webapp_1  |     self._wrap_pool_connect(self.pool.connect, None),
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2151, in _wrap_pool_connect
    webapp_1  |     e, dialect, self)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 1465, in _handle_dbapi_exception_noconnection
    webapp_1  |     exc_info
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 203, in raise_from_cause
    webapp_1  |     reraise(type(exception), exception, tb=exc_tb, cause=cause)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 186, in reraise
    webapp_1  |     raise value.with_traceback(tb)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/base.py", line 2147, in _wrap_pool_connect
    webapp_1  |     return fn()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 387, in connect
    webapp_1  |     return _ConnectionFairy._checkout(self)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 766, in _checkout
    webapp_1  |     fairy = _ConnectionRecord.checkout(pool)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 516, in checkout
    webapp_1  |     rec = pool._do_get()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 1138, in _do_get
    webapp_1  |     self._dec_overflow()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
    webapp_1  |     compat.reraise(exc_type, exc_value, exc_tb)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/util/compat.py", line 187, in reraise
    webapp_1  |     raise value
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 1135, in _do_get
    webapp_1  |     return self._create_connection()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 333, in _create_connection
    webapp_1  |     return _ConnectionRecord(self)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 461, in __init__
    webapp_1  |     self.__connect(first_connect_check=True)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/pool.py", line 651, in __connect
    webapp_1  |     connection = pool._invoke_creator(self)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/strategies.py", line 105, in connect
    webapp_1  |     return dialect.connect(*cargs, **cparams)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/sqlalchemy/engine/default.py", line 393, in connect
    webapp_1  |     return self.dbapi.connect(*cargs, **cparams)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/pymysql/__init__.py", line 94, in Connect
    webapp_1  |     return Connection(*args, **kwargs)
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/pymysql/connections.py", line 325, in __init__
    webapp_1  |     self.connect()
    webapp_1  |   File "/usr/local/lib/python3.6/site-packages/pymysql/connections.py", line 630, in connect
    webapp_1  |     raise exc
    webapp_1  | sqlalchemy.exc.OperationalError: (pymysql.err.OperationalError) (2003, "Can't connect to MySQL server on '127.0.0.1' ([Errno 111] Connection refused)")
    
    8 条回复    2019-05-07 14:11:36 +08:00
    fngtz
        1
    fngtz  
       2019-05-06 23:34:18 +08:00 via iPhone
    Eds1995
        2
    Eds1995  
       2019-05-06 23:36:15 +08:00
    先在部署 flask 的终端里测试 telnet 127.0.0.1 2003 能不能连通
    WilliamYang
        3
    WilliamYang  
       2019-05-06 23:41:16 +08:00
    好好看一下 1L 的文档
    toono
        4
    toono  
       2019-05-07 01:11:48 +08:00 via iPhone
    1. 确认 mysql 的 3306 端口已经映射到宿主机上;
    2. 如果 flask 程序是在另一个容器内,通过 localhost 是不能访问到的,需要 docker-compose 的 link,访问对应的 hosts,或者访问宿主机的 ip 也可以。
    ebingtel
        5
    ebingtel  
       2019-05-07 09:03:15 +08:00
    network mode 设置成 host 模式,就能访问了……因为在多个容器里面,使用 localhost (指的是各个容器内部了), 所以不同,方案 见 1L
    yuting0501
        6
    yuting0501  
    OP
       2019-05-07 09:24:35 +08:00
    原来如此,谢谢大家!
    yuting0501
        7
    yuting0501  
    OP
       2019-05-07 09:42:15 +08:00   ❤️ 1
    更新一下状态,将`127.0.0.1`改为我的 mysql 容器名 mysql 指定网络名后解决问题:

    ```
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:[email protected]:3306/my_database?charset=utf8'
    SQLALCHEMY_DATABASE_URI = 'mysql+pymysql://root:my_password@mysql:3306/my_database?charset=utf8'
    ```

    希望能帮到和我一样的新手
    julyclyde
        8
    julyclyde  
       2019-05-07 14:11:36 +08:00
    这就是用 docker 没事找事搞出来的
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5448 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 35ms · UTC 08:32 · PVG 16:32 · LAX 00:32 · JFK 03:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.