在python中执行SQL文件中的多个SQL命令

问题描述 投票:0回答:1

在 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 连接器抛出错误。您能指导解决这个问题吗?

python mysql mysql-connector
1个回答
0
投票

您遇到的问题是由于

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
行和
$$
符号,您的代码应该可以正常工作

© www.soinside.com 2019 - 2024. All rights reserved.