首页 > 解决方案 > 如何将 dockerized python 脚本链接到 mysql docker 容器以在同一主机上加载数据?

问题描述

我在 Ubuntu 16.04 机器上mysql运行了两个 docker 容器,一个 docker 容器运行了一个服务器,另一个容器包含一个 dockerizedpython脚本集,每分钟运行一个 cron 作业,将数据加载到mysql. 如何连接两者以通过python脚本将数据加载到mysql容器中?我出现了一个错误:这是我的相关命令:

MYSQL 容器运行没有问题:

docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=yourPassword --name icarus -d mysql_docker_image

CONTAINER ID        IMAGE                             COMMAND                  CREATED             STATUS                    PORTS                               NAMES
927e50ca0c7d        mysql_docker_image                "docker-entrypoint.s…"   About an hour ago   Up About an hour          0.0.0.0:3306->3306/tcp, 33060/tcp   icarus

第二个容器包含 cron 和 python 脚本:

 #build the container without issue    
    sudo docker run -t -i -d docker-cron

    #exec into it to check logs
    sudo docker exec -i -t container_id /bin/bash

    #check logs
    root@b149b5e7306d:/# cat /var/log/cron.log

错误:

出现以下错误,我认为这与错误的主机地址有关:

Caught this error: OperationalError('(pymysql.err.OperationalError) (2003, "Can\'t connect to MySQL server on \'localhost\' ([Errno 99] Cannot assign requested address)")',)

Python脚本:

from traffic.data import opensky
from sqlalchemy import create_engine
#from sqlalchemy_utils import database_exists, create_database
import sqlalchemy
import gc


#connection and host information
host = 'localhost'
db='icarus'
engine = create_engine('mysql+pymysql://root:password@'+ host+ ':3306/'+ db) #create engine connection
version= sys.version_info[0]

#functions to upload data
def upload(df,table_name):
    df.to_sql(table_name,con=engine,index=False,if_exists='append')
    engine.dispose()
    print('SUCCESSFULLY LOADED DATA INTO STAGING...')

#pull data drom api
sv = opensky.api_states()
final_df = sv.data
#quick column clean up 
print(final_df.head())
final_df=final_df.rename(columns = {'timestamp':'time_stamp'})


#insert data to staging
try:
    upload(final_df, 'flights_stg')
except Exception as error:
        print('Caught this error: ' + repr(error))
del(final_df)
gc.collect()

我假设错误是使用“localhost”作为我的地址?我将如何解决这样的问题?

更多信息:

MYSQL Docker 文件:

FROM mysql
COPY init.sql /docker-entrypoint-initdb.d

Python Docker 文件:

FROM ubuntu:latest

WORKDIR /usr/src/app

#apt-get install -y build-essential -y  python python-dev python-pip python-virtualenv libmysqlclient-dev curl&& \

RUN \
  apt-get update && \
  apt-get install -y build-essential -y git -y  python3.6 python3-pip libproj-dev proj-data proj-bin libgeos++-dev libmysqlclient-dev python-mysqldb curl&& \
  rm -rf /var/lib/apt/lists/*

COPY requirements.txt ./
RUN pip3 install --upgrade pip && \
    pip3 install --no-cache-dir -r requirements.txt

RUN pip3 install --upgrade setuptools
RUN pip3 install git+https://github.com/xoolive/traffic

COPY . .

# Install cron
RUN apt-get update
RUN apt-get install cron

# Add crontab file in the cron directory
ADD crontab /etc/cron.d/simple-cron

# Add shell script and grant execution rights
ADD script.sh /script.sh
RUN chmod +x /script.sh

# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/simple-cron

# Create the log file to be able to run tail
RUN touch /var/log/cron.log

# Run the command on container startup
CMD cron && tail -f /var/log/cron.log

标签: pythonmysqldockerdocker-build

解决方案


你能从 MySQL 容器中分享你的 dockerfile 或 compose 文件吗?是的,与使用 localhost 作为主机有关的问题。您必须使用 docker 服务名称作为主机。所以在 docker 服务名称作为 DNS。例如,如果您的 docker-compose 看起来像:

services:
mydb:
 image: mysql:5.7
 command: --default-authentication-plugin=mysql_native_password
 restart: always
 environment:
   MYSQL_ROOT_PASSWORD:root
   MYSQL_USER: root
   MYSQL_PASSWORD: root
   MYSQL_DATABASE: root

您必须使用mydb而不是 localhost


推荐阅读