Docker Compose:第1行的MySQL语法错误“ DELIMITER”

时间:2018-08-17 08:05:18

标签: mysql docker phpmyadmin

我有一个问题,我想让Docker Compose在设置MySQL之后直接导入我的Database.sql文件。但这总是抛出错误:

  

您的SQL语法有错误;请查看与您的MySQL服务器版本相对应的手册,以在'DELIMITER |'附近使用正确的语法在第1行

但是以某种方式,当我通过浏览器中的phpMyAdmin导入它时,它工作得很好。

这是我的docker-compose.yml

version: "3.2"
services:
  php:
    build: './php/'
    networks:
      - backend
    volumes:
      - ./www/:/var/www/html/
  apache:
    build: './apache/'
    depends_on:
      - php
      - mysql
    networks:
      - frontend
      - backend
    ports:
      - "8081:80"
    volumes:
      - ./www/:/var/www/html/
  mysql:
    image: mysql:5.7
    volumes:
      - ./mysql:/tmp/database
    command: mysqld --max_allowed_packet=32505856 --user=root --init-file="/tmp/database/schema.sql"
    networks:
      - backend
    environment:
      - MYSQL_ROOT_PASSWORD=root
  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    links:
        - mysql
    ports:
      - '8082:80'
    environment:
      MYSQL_USERNAME: root
      MYSQL_ROOT_PASSWORD: root
      PMA_HOST: mysql
    networks:
      - backend
networks:
  frontend:
  backend:

这是我的.sql文件的示例片段,该片段被执行:

-- phpMyAdmin SQL Dump
-- version 4.8.2
-- https://www.phpmyadmin.net/
--
-- Host: mysql
-- Generation Time: Aug 20, 2018 at 08:30 AM
-- Server version: 5.7.23
-- PHP Version: 7.2.6
DELIMITER $$

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";

--
-- Database: `database`
--
CREATE DATABASE IF NOT EXISTS `databasetest` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci;
USE `databasetest`;

--
-- Procedures
--
DROP PROCEDURE IF EXISTS `sp_filestatus_get`$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_filestatus_get` (IN `filename_name` VARCHAR(500), IN `kampagne_name` VARCHAR(100), IN `outlet_name` VARCHAR(100))  NO SQL

... Some more stuff

END;

我是否错过了配置中的某些内容?还是为什么它不能与compose一起使用,而是直接在phpMyAdmin中起作用?

2 个答案:

答案 0 :(得分:0)

SQL API不直接支持DELIMETER,因为该语句的支持是由客户端定义的,因此它在phpmyadmin中有效,因为它支持该语句。默认的mysql客户端使用delimeter语句,遵循Stored programs defining中建议的步骤并相应地更新sql文件({CREATE PROCEDURE将替换为您的sql语句)。

mysql> delimiter //

mysql> CREATE PROCEDURE dorepeat(p1 INT)
    -> BEGIN
    ->   SET @x = 0;
    ->   REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT;
    -> END
    -> //
Query OK, 0 rows affected (0.00 sec)

mysql> delimiter ;

根据您使用的脚本,与现在相比,您必须以不同的方式处理分隔符:

替换

DROP PROCEDURE IF EXISTS `sp_filestatus_get`$$

DROP PROCEDURE IF EXISTS `sp_filestatus_get`;

另外,请将END;替换为END $$,并在文件末尾添加DELIMITER ;

这里有一些链接可用于您在init sql脚本中查找需要调整的内容:

答案 1 :(得分:0)

如果您确实需要DELIMITER语句,则可以将mysql命令更改为

bash -c "service mysql start && echo 'xxxxxxxxxxxxxxxxx' && mysql --max_allowed_packet=32505856 -u root -proot < /tmp/database/schema.sql && while true; do sleep 1; done"

然后它应该可以正常工作,而无需进行其他任何更改。

所以您的mysql-section应该看起来像这样:

  mysql:
    image: mysql:5.7
    volumes:
      - ./mysql:/tmp/database
    command: bash -c "service mysql start && echo 'xxxxxxxxxxxxxxxxx' && mysql --max_allowed_packet=32505856 -u root -proot < /tmp/database/schema.sql && while true; do sleep 1; done"
    networks:
      - backend
    environment:
      - MYSQL_ROOT_PASSWORD=root

为什么会起作用:

之前,您使用mysqld命令启动mysql-server并指定了初始化脚本。现在,它作为服务启动。这带来了一个优点和一个缺点。

  • 优点:您现在可以使用mysql命令连接到mysql服务器。
  • 缺点:指定了mysql命令后,该容器将被docker停止。

为解决该缺点,我添加了while true; do sleep 1; done作为最后一个命令。这将导致容器运行直到停止。 echo ist只是为了让您看到命令已执行。