将CSV文件上载到MySQL Docker容器时的权限问题

时间:2018-06-18 15:57:54

标签: mysql docker

我正在创建一个MySQL 5.7 Docker容器,并希望在容器启动时创建和填充数据库。

首先,Dockerfile:

FROM mysql:5.7

VOLUME /var/lib/mysql-files

ADD ./scripts/kdd_db_create_tables.sql /docker-entrypoint-initdb.d/kdd_db_create_tables.sql

接下来,kdd_db_create_tables.sql

的内容
DROP DATABASE IF EXISTS cdl;
CREATE DATABASE cdl;
USE cdl;

DROP TABLE IF EXISTS kdd;
CREATE TABLE kdd (
   duration BIGINT,
   protocol_type TEXT,
   ..
   class TEXT);

LOAD DATA LOCAL INFILE '/var/lib/mysql-files/kdd_dataset.csv' INTO TABLE kdd FIELDS TERMINATED BY ',';

ALTER TABLE kdd ADD id INT NOT NULL AUTO_INCREMENT PRIMARY KEY;

最后,docker-compose文件:

---
version: '3.5'
services:
  mysql:
    image: ericsson/mysql5.7:latest
    networks:
      - cdl_net
    ports:
      - 3306:3306
    hostname: mysql
    container_name: mysql
    volumes:
      - ./mysql/data:/var/lib/mysql-files
    environment:
      MYSQL_ROOT_PASSWORD: cdl
      MYSQL_USER: cdl
      MYSQL_PASSWORD: cdl
      MYSQL_DATABASE: cdl

networks:
  cdl_net:
    driver: bridge
     name: cdl_net

文件结构如下:

|-- docker-compose.yml
|-- mysql
    |-- Dockerfile
    |-- data
    |   |-- kdd_dataset.csv
    |-- scripts
        |-- kdd_db_create_tables.sql

即,SQL脚本位于./mysql/scripts,而数据集位于./mysql/data。在容器执行时,SQL脚本在容器中的文件夹/docker-entrypoint-initdb.d中可用,而数据集在/var/lib/mysql-files中(因为LOAD DATA INFILE要求文件位于所述文件夹中)。但是,当我运行容器时,我收到以下错误:

ERROR 13 (HY000) at line 50: File '/var/lib/mysql-files/kdd_dataset.csv' not found (Errcode: 13 - Permission denied)

对我做错了什么的想法?

2 个答案:

答案 0 :(得分:0)

好吧,问题似乎出在我的(内部)基础架构提供商提供我的房屋的方式上。不可能在我家中挂任何东西:-(

改为使用/ tmp

答案 1 :(得分:0)

我遇到了同样的问题,这是我为解决此问题所做的事情。

1)Dokerfile

FROM mysql:5.7

# Add a database
ENV MYSQL_DATABASE abahet

# Add the create.sql to the docker image
# All scripts in docker-entrypoint-initdb.d/ are automatically
# executed during container startup
COPY ./create.sql /docker-entrypoint-initdb.d/

# Copy the csv file to /var/lib/mysql-files/ 
COPY ./ratings.csv /var/lib/mysql-files/

2)容器启动脚本(database.sh)

#!/bin/bash

CMD=$1

IMAGE_TAG=latest

IMAGE_NAME="my-database"

CONTAINER_NAME="my-database"

DATABASE_NAME="test_db"

MYSQL_ROOT_PASSWORD="root"

DATABASE_PORT="3306"

case $CMD in
    build)
        docker build -t  $IMAGE_NAME .
        ;;
    start)
        CMD="docker run"
        CMD="$CMD --rm"
        CMD="$CMD --net=bridge"
        CMD="$CMD --name $CONTAINER_NAME"
        CMD="$CMD -p $DATABASE_PORT:$DATABASE_PORT"
        CMD="$CMD -e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD"
        CMD="$CMD -td $IMAGE_NAME:$IMAGE_TAG"
        echo "$CMD"
        eval $CMD
        ;;
    init)
        CMD="docker run"
        CMD="$CMD --rm"
        CMD="$CMD --net=bridge"
        CMD="$CMD --name $CONTAINER_NAME"
        CMD="$CMD -p $DATABASE_PORT:$DATABASE_PORT"
        CMD="$CMD -e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD"
        CMD="$CMD -td $IMAGE_NAME:$IMAGE_TAG"
        echo "$CMD"
        eval $CMD;

        echo "Waiting for mysql start"
        while ! docker exec -it  $CONTAINER_NAME mysqladmin -p$MYSQL_ROOT_PASSWORD ping &>/dev/null ; do sleep 1 ; done

        sleep 10

        echo "Loading database data"
        docker exec -it $CONTAINER_NAME mysql -p$MYSQL_ROOT_PASSWORD $DATABASE_NAME -e "LOAD DATA LOCAL INFILE 'var/lib/mysql-files/ratings.csv' INTO TABLE rating FIELDS TERMINATED BY ',' ENCLOSED BY '\"' LINES TERMINATED BY '\n'";

        ;;
    stop)
        docker stop $CONTAINER_NAME
        ;;
    remove)
        docker rm -f $CONTAINER_NAME
        ;;
    rmi)
        docker rmi -f $CONTAINER_NAME
        ;;
    *)
        echo "Usage : build | start <image_tag> | stop | remove | rmi"
        ;;
esac

exit 0

3)用法:

在终端中执行以下步骤:

 #Build the docker image
./database build 

 #Init the container (start + import data)
./database init