[英]How to connect to a mysql database on localhost from a python script in a docker container
I have a mysql database running on a localhost (ubuntu 16.04). 我有一个在本地主机(ubuntu 16.04)上运行的mysql数据库。 On the same host I have a docker container in which a python script is running.
在同一主机上,我有一个运行python脚本的docker容器。 This script has to connect to the mysqldb on the local host.
该脚本必须连接到本地主机上的mysqldb。 As was described in these posts ( post1 , post2 ) I set bind-address=0.0.0.0 for my local database and found the ip-address of my local host and used it in my python script to connect to the database, but it did not work.
如这些帖子( post1 , post2 )中所述,我为本地数据库设置了bind-address = 0.0.0.0,找到了本地主机的ip地址,并在python脚本中使用了它来连接到数据库,但是它确实不行。 Below I show my set-up and how I run the docker container.
下面显示了我的设置以及如何运行docker容器。 My python script (analysis.py) looks as follows:
我的python脚本(analysis.py)如下所示:
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()
My Dockerfile looks as follwos: 我的Dockerfile看起来像:
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
Finally, the requirements.txt looks like 最后,requirements.txt看起来像
mysql-connector-python
sqlalchemy
pandas
I build the docker image as follows: 我按如下方式构建docker映像:
docker build -t max_age_app .
Then I start the container using this image as follows: 然后,我使用此图像启动容器,如下所示:
docker run -d max_age_app:latest
The container exits with exit code 1 and when I take a look at the respective log of the container I find the following error in it: 容器以退出代码1退出,当我查看容器的相应日志时,发现其中存在以下错误:
> 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)
In order to determine the ip of the localhost I used ifconfig
command, which yielded something like this: 为了确定本地主机的IP,我使用了
ifconfig
命令,它产生了如下所示的内容:
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
So I tried 172.17.0.1 in order to connect to the local database from within the container but it did not work. 因此,我尝试了172.17.0.1,以便从容器内连接到本地数据库,但是它不起作用。
Do I have to match any ports between the container and the localhost via the -p
option when I start the container? 启动容器时,是否需要通过
-p
选项匹配容器和localhost之间的任何端口?
I would appreciate any help. 我将不胜感激任何帮助。
You shouldn't EXPOSE
the port 3306 on the container, since the MySQL server is listening outside it, on the localhost. 您不应该在容器上
EXPOSE
端口3306,因为MySQL服务器正在本地主机上监听它。 I suspect it's a networking issue, so try to see if the localhost has the interface with the address 172.17.0.1
and if you can reach this address from inside your container (ex. try docker exec -ti _your_container_name /bin/sh
and then try ping 172.17.0.1
). 我怀疑这是网络问题,因此请尝试查看本地主机是否具有地址为
172.17.0.1
的接口,以及是否可以从容器内部访问此地址(例如,尝试docker exec -ti _your_container_name /bin/sh
,然后尝试ping 172.17.0.1
)。 You should also check the mysql logs to see if you have some error reported there. 您还应该检查mysql日志,看看那里是否报告了一些错误。
In order to solve this problem one has to correctly configure the mysql database on the localhost. 为了解决这个问题,必须在本地主机上正确配置mysql数据库。 In addition to what was discussed above one has to do the following steps:
除了上面讨论的内容外,还必须执行以下步骤:
docker inspect <container_name>
. docker inspect <container_name>
。 Afterwards, simply starting the container with the command docker run -d max_age_app
will suffice for the python script to write the data into the database on the localhost. 然后,只需使用命令
docker run -d max_age_app
启动容器,Python脚本就足以将数据写入本地主机上的数据库。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.