在 python mysql-connector 代码中运行 SQL 文件时遇到问题。
在SQL文件中,它包含函数、过程以及insert和create语句的组合。 我正在使用 mysql-connector-python 包,这是我的代码:
Python 代码
import mysql.connector
# Connect to MySQL server
con = mysql.connector.connect(
host="127.0.0.1",
user="master",
passwd="mmmmmmm$",
database="cl",
port="3306"
)
# Create a cursor
cur = con.cursor(dictionary=True)
with open('a.sql', 'r') as sql_file:
result_iterator = cur.execute(sql_file.read(), multi=True)
for res in result_iterator:
print("Running query: ", res) # Will print out a short representation of the query
print(f"Affected {res.rowcount} rows" )
con.commit() # Remember to commit all your changes!
# Close the cursor
cur.close()
并在 SQL 文件中
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
DELIMITER $$
--
-- Procedures
--
CREATE PROCEDURE `CONSUMER_PATH` (IN `input` INT, OUT `output` VARCHAR(128)) Begin
DECLARE _id INT;
DECLARE _parent INT;
DECLARE _path VARCHAR(128);
SET `max_sp_recursion_depth` = 50;
SELECT `id`, `parent_location_id`
INTO _id, _parent
FROM `locations`
WHERE `id` = `input` and `deleted`=0 and `record_status`=1;
IF _parent IS NULL THEN
SET _path = _id;
ELSE
CALL `LOCATION_PATH`(_parent, _path);
SELECT CONCAT(_path, ',', _id) INTO _path;
END IF;
SELECT _path INTO `output`;
END$$
--
-- Functions
--
CREATE FUNCTION `GET_CHILD_LOCATIONS` (`input` INT) RETURNS VARCHAR(128) CHARSET utf8mb4 COLLATE utf8mb4_general_ci BEGIN
CALL `LOCATION_PATH`(`input`, @path);
RETURN @path;
END$$
DELIMITER ;
-- --------------------------------------------------------
--
-- Table structure for table `access_controls`
--
CREATE TABLE `access_controls` (
`id` int(11) NOT NULL,
`endpoint_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT 0,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
运行Python代码时,抛出错误
se near 'DELIMITER $$
--
-- Procedures
--
CREATE PROCEDURE `CONSUMER_PATH` (IN `input`...' at line 1
直接在MySQL命令中工作正常。在 python 中,mysql 连接器抛出错误。您能指导解决这个问题吗?
您遇到的问题是由于
mysql.connector
不支持 DELIMITER
声明造成的。 DELIMITER
语句用于MySQL命令行客户端或一些图形界面中,表示语句的结束,默认分隔符是分号;。但是,在 SQL 文件中,您使用 DELIMITER
语句将过程和函数的分隔符重新定义为 $$
。
由于
mysql.connector
不理解DELIMITER
语句,您需要修改SQL文件以删除DELIMITER
语句并相应地调整过程和函数。您可以执行以下操作:
从 SQL 文件中删除
DELIMITER
语句。使用 mysql.connector
执行 SQL 语句时不需要它们。
删除每个过程和函数定义末尾的
$$
。就留下END
吧。
这是 SQL 文件的修改版本:
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
--
-- Procedures
--
CREATE PROCEDURE `CONSUMER_PATH` (IN `input` INT, OUT `output` VARCHAR(128))
BEGIN
DECLARE _id INT;
DECLARE _parent INT;
DECLARE _path VARCHAR(128);
SET `max_sp_recursion_depth` = 50;
SELECT `id`, `parent_location_id`
INTO _id, _parent
FROM `locations`
WHERE `id` = `input` and `deleted`=0 and `record_status`=1;
IF _parent IS NULL THEN
SET _path = _id;
ELSE
CALL `LOCATION_PATH`(_parent, _path);
SELECT CONCAT(_path, ',', _id) INTO _path;
END IF;
SELECT _path INTO `output`;
END;
--
-- Functions
--
CREATE FUNCTION `GET_CHILD_LOCATIONS` (`input` INT) RETURNS VARCHAR(128) CHARSET utf8mb4 COLLATE utf8mb4_general_ci
BEGIN
CALL `LOCATION_PATH`(`input`, @path);
RETURN @path;
END;
-- --------------------------------------------------------
--
-- Table structure for table `access_controls`
--
CREATE TABLE `access_controls` (
`id` int(11) NOT NULL,
`endpoint_id` int(11) NOT NULL,
`role_id` int(11) NOT NULL,
`deleted` tinyint(1) NOT NULL DEFAULT 0
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;
通过这些更改,当使用 Python 代码执行时,您的 SQL 文件应该与
mysql.connector
库兼容。删除 DELIMITER
行和 $$
符号,您的代码应该可以正常工作