Столкнулся с тем, что yoyo migrations не может развернуть БД на mysql, в которой объявляются процедуры с REPEAT.

Допустим, мы хотим использовать чуть подчищенный вариат дампа произведенного с помощью mysqldump:

DROP TABLE IF EXISTS `test_table`;
CREATE TABLE `test_table` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(8) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;

DROP TABLE IF EXISTS `yoyo_lock`;
CREATE TABLE `yoyo_lock` (
`locked` int NOT NULL DEFAULT '1',
`ctime` timestamp NULL DEFAULT NULL,
`pid` int NOT NULL,
PRIMARY KEY (`locked`)
) ENGINE=InnoDB;

DELIMITER ;;
CREATE DEFINER=`root`@`%` FUNCTION `test_function`() RETURNS int
READS SQL DATA
DETERMINISTIC
begin
declare test_var int default 1;
repeat
set test_var = test_var + 1;
until test_var < 10 end repeat;
return test_var;
end ;;

CREATE DEFINER=`root`@`%` PROCEDURE `test_procedure`()
begin
declare test_var int default 1;
repeat
set test_var = test_var + 1;
until test_var < 10 end repeat;
end ;;
DELIMITER ;


Как видим, mysql его спокойно разворачивает:

[popov-aa@archlinux yoyo]$ mysql -u root -p -h 172.28.1.21 test_db < ./migrations/20200717_01_dHiTT-create-schema.sql 
Enter password:
[popov-aa@archlinux yoyo]$

Теперь попробуем развернуть этот же дамп с помощью yoyo, получаем ошибку:

DROP TABLE IF EXISTS `test_table`;
CREATE TABLE `test_table` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(8) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;

DROP TABLE IF EXISTS `yoyo_lock`;
CREATE TABLE `yoyo_lock` (
`locked` int NOT NULL DEFAULT '1',
`ctime` timestamp NULL DEFAULT NULL,
`pid` int NOT NULL,
PRIMARY KEY (`locked`)
) ENGINE=InnoDB;

CREATE DEFINER=`root`@`%` FUNCTION `test_function`() RETURNS int
READS SQL DATA
DETERMINISTIC
begin
declare test_var int default 1;
repeat
set test_var = test_var + 1;
until test_var < 10 end repeat;
return test_var;
end ;

CREATE DEFINER=`root`@`%` PROCEDURE `test_procedure`()
begin
declare test_var int default 1;
repeat
set test_var = test_var + 1;
until test_var < 10 end repeat;
end ;

Получаем:
[popov-aa@archlinux yoyo]$ yoyo apply
/home/popov-aa/.local/lib/python3.8/site-packages/pymysql/cursors.py:170: Warning: (1051, "Unknown table 'test_db.test_table'"
result = self._query(query)
Traceback (most recent call last):
...
pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'DELIMITER' at line 1"
[popov-aa@archlinux yoyo]$

Модифицируем дамп, удалив DELIMITER:
[popov-aa@archlinux yoyo]$ yoyo apply
Traceback (most recent call last):
...
pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 8"
[popov-aa@archlinux yoyo]$

При этом вариант без REPEAT проходит на ура:
DROP TABLE IF EXISTS `test_table`;
CREATE TABLE `test_table` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(8) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;

DROP TABLE IF EXISTS `yoyo_lock`;
CREATE TABLE `yoyo_lock` (
`locked` int NOT NULL DEFAULT '1',
`ctime` timestamp NULL DEFAULT NULL,
`pid` int NOT NULL,
PRIMARY KEY (`locked`)
) ENGINE=InnoDB;

CREATE DEFINER=`root`@`%` FUNCTION `test_function`() RETURNS int
READS SQL DATA
DETERMINISTIC
begin
declare test_var int default 1;
return test_var;
end ;

CREATE DEFINER=`root`@`%` PROCEDURE `test_procedure`()
begin
declare test_var int default 1;
end ;

[popov-aa@archlinux yoyo]$ yoyo apply
[popov-aa@archlinux yoyo]$

У кого-нибудь есть догадки в чем проблема и как быть?








 ,






URL записи