首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从docker容器中的python脚本连接本地主机上的mysql数据库

如何从docker容器中的python脚本连接本地主机上的mysql数据库
EN

Stack Overflow用户
提问于 2019-01-05 00:34:49
回答 2查看 3.9K关注 0票数 0

我有一个mysql数据库运行在本地主机上(ubuntu16.04)。在同一台主机上,我有一个用于运行python脚本的docker容器。此脚本必须连接到本地主机上的mysqldb。正如在这些帖子(post1post2)中所描述的,我为本地数据库设置了bind=0.0.0.0,并找到了本地主机的ip地址,并在我的python中使用它连接到数据库,但是它没有工作。下面我展示了我的设置和如何运行码头集装箱。我的python脚本(analysis.py)如下所示:

代码语言:javascript
复制
import pandas as pd
import sqlalchemy as db

def find_max_age():
   cnx = db.create_engine('mysql+mysqlconnector://root:password@172.17.0.1:3306/datasets')
   cnx_res = db.create_engine('mysql+mysqlconnector://root:password@172.17.0.1:3306/results')
   df = pd.read_sql("select * from test_table", cnx)
   idx = df['age'].idxmax() == df.index
   df_res = df[idx]

   df_res.to_sql('max_age4', con=cnx_res, index=False)


if __name__ == '__main__':
   find_max_age()

我的Dockerfile看起来像follwos:

代码语言:javascript
复制
FROM python:2.7-slim
EXPOSE 80 3306
WORKDIR /app
COPY requirements.txt /app
RUN pip install -r requirements.txt
COPY analysis.py /app
CMD python analysis.py

最后,requirements.txt看起来就像

代码语言:javascript
复制
mysql-connector-python
sqlalchemy
pandas

我构建了码头形象如下:

代码语言:javascript
复制
docker build -t max_age_app .

然后,我使用以下映像启动容器:

代码语言:javascript
复制
docker run -d max_age_app:latest

容器以退出代码1退出,当我查看容器的相应日志时,会在其中发现以下错误:

代码语言:javascript
复制
> Traceback (most recent call last):
  File "analysis.py", line 24, in <module>
    find_max_age()
  File "analysis.py", line 11, in find_max_age
    df = pd.read_sql("select * from test_table", cnx)
  File "/usr/local/lib/python2.7/site-packages/pandas/io/sql.py", line 397, in read_sql
    chunksize=chunksize)
  File "/usr/local/lib/python2.7/site-packages/pandas/io/sql.py", line 1063, in read_query
    result = self.execute(*args)
  File "/usr/local/lib/python2.7/site-packages/pandas/io/sql.py", line 954, in execute
    return self.connectable.execute(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 2074, in execute
    connection = self.contextual_connect(close_with_result=True)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 2123, in contextual_connect
    self._wrap_pool_connect(self.pool.connect, None),
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 2162, in _wrap_pool_connect
    e, dialect, self)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 1476, in _handle_dbapi_exception_noconnection
    exc_info
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/util/compat.py", line 265, in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/base.py", line 2158, in _wrap_pool_connect
    return fn()
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/pool.py", line 400, in connect
    return _ConnectionFairy._checkout(self)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/pool.py", line 788, in _checkout
    fairy = _ConnectionRecord.checkout(pool)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/pool.py", line 529, in checkout
    rec = pool._do_get()
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/pool.py", line 1193, in _do_get
    self._dec_overflow()
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 66, in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/pool.py", line 1190, in _do_get
    return self._create_connection()
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/pool.py", line 347, in _create_connection
    return _ConnectionRecord(self)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/pool.py", line 474, in __init__
    self.__connect(first_connect_check=True)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/pool.py", line 671, in __connect
    connection = pool._invoke_creator(self)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/strategies.py", line 106, in connect
    return dialect.connect(*cargs, **cparams)
  File "/usr/local/lib/python2.7/site-packages/sqlalchemy/engine/default.py", line 412, in connect
    return self.dbapi.connect(*cargs, **cparams)
  File "/usr/local/lib/python2.7/site-packages/mysql/connector/__init__.py", line 172, in connect
    return CMySQLConnection(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/mysql/connector/connection_cext.py", line 78, in __init__
    self.connect(**kwargs)
  File "/usr/local/lib/python2.7/site-packages/mysql/connector/abstracts.py", line 731, in connect
    self._open_connection()
  File "/usr/local/lib/python2.7/site-packages/mysql/connector/connection_cext.py", line 179, in _open_connection
    sqlstate=exc.sqlstate)
sqlalchemy.exc.DatabaseError: (mysql.connector.errors.DatabaseError) 2003 (HY000): Can't connect to MySQL server on '172.17.0.1' (111) (Background on this error at: http://sqlalche.me/e/4xp6)

为了确定本地主机的ip,我使用了ifconfig命令,得到如下结果:

代码语言:javascript
复制
docker0   Link encap:Ethernet  HWaddr 02:42:a2:a6:d7:ff  
          inet addr:172.17.0.1 

enp0s3    Link encap:Ethernet  HWaddr 08:00:27:bb:7e:b5  
          inet addr:10.0.2.15 

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1 

因此,为了从容器中连接本地数据库,我尝试了172.17.0.1,但是它没有工作。

启动容器时,是否必须通过-p选项匹配容器和本地主机之间的任何端口?

我很感谢你的帮助。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-05 14:37:44

为了解决这个问题,必须在本地主机上正确配置mysql数据库。除上文讨论的内容外,还必须采取以下步骤:

  • 使用python应用程序查找您的停靠容器的IP地址。您可以使用docker inspect <container_name>
  • 在本地mysql数据库中为该IP地址创建一个新用户(以及相应的密码)。有关如何做到这一点的信息,你可以在这个post中找到。介绍了如何在mysql中设置密码策略。

之后,使用命令docker run -d max_age_app启动容器就足以让python将数据写入本地主机上的数据库中。

票数 0
EN

Stack Overflow用户

发布于 2019-01-05 00:46:27

您不应该在容器上EXPOSE端口3306,因为MySQL服务器正在侦听它外部的本地主机。我怀疑这是一个网络问题,所以试着看看本地主机是否有与地址172.17.0.1的接口,以及您是否可以从容器内(例如)到达这个地址。尝试docker exec -ti _your_container_name /bin/sh,然后尝试ping 172.17.0.1)。您还应该检查mysql日志,看看那里是否报告了一些错误。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54047890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档