通过 SQLAlchemy 将存储过程定义传递给 singlestore/memsql
Pass stored procedure definition to singlestore/memsql via SQLAlchemy
我在文件 stored_procedure.sql
中存储了一个存储过程 (ha)。如果我在 SQL 编辑器软件中打开这个文件,我可以定义过程并在 Python 或 SQL 中调用它。该过程如下所示:
CREATE OR REPLACE PROCEDURE
test_proc (some_date VARCHAR(10))
RETURNS INT AS
BEGIN
INSERT INTO db.test
-- join TABLE 1 and TABLE 2 for final results
SELECT some_date;
RETURN 1;
END //
DELIMITER ;
但是,我希望 Python 能够读取过程文件,并将存储过程传递给数据库(如果存储过程得到更新但没有手动重新 运行 , 代码拾取程序的重新定义)。
当我将存储过程读入文本流并尝试执行时:
from sqlalchemy import create_engine
conn = create_engine(parameters_to_connect_to_database)
statement = open('stored_procedure.sql').read()
trans = conn.begin()
conn.execute(statement)
trans.commit()
conn.execute(statement)
的语法错误如下:
ProgrammingError: (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 //\nCREATE OR REPLACE PROCEDURE
我知道 sql 脚本实际上没有语法错误,因为如果我在 sql 编辑器软件中,它可以手动运行。如果我将存储过程文件与其中包含 create table 或 insert into 语句的文件交换,则不会返回任何错误并且插入成功。
我如何编辑上面的文件以执行其中包含 SQL 语句的文件,以及其中写入存储过程的文件?
DELIMITER
不是 SQL 语句。它是一个命令,可帮助 MySQL shell 避免混淆关于如何解释 ;
当它出现在存储过程定义中时,存储过程定义本身是 CREATE PROCEDURE 语句的一部分。当 运行 shell 之外的 CREATE PROCEDURE 语句时,DELIMITER
不是必需的(或有效的)。
这失败了:
import sqlalchemy as sa
engine = sa.create_engine("mysql+pymysql://scott:tiger@localhost:3307/mydb")
drop_sp = "DROP PROCEDURE IF EXISTS test_proc"
create_sp = """\
CREATE DEFINER=`root`@`localhost` PROCEDURE `test_proc`()
BEGIN
SELECT 'this is a test';
END //
DELIMITER ;
"""
with engine.begin() as conn:
conn.exec_driver_sql(drop_sp)
conn.exec_driver_sql(create_sp)
但这行得通
import sqlalchemy as sa
engine = sa.create_engine("mysql+pymysql://scott:tiger@localhost:3307/mydb")
drop_sp = "DROP PROCEDURE IF EXISTS test_proc"
create_sp = """\
CREATE DEFINER=`root`@`localhost` PROCEDURE `test_proc`()
BEGIN
SELECT 'this is a test';
END
"""
with engine.begin() as conn:
conn.exec_driver_sql(drop_sp)
conn.exec_driver_sql(create_sp)
我在文件 stored_procedure.sql
中存储了一个存储过程 (ha)。如果我在 SQL 编辑器软件中打开这个文件,我可以定义过程并在 Python 或 SQL 中调用它。该过程如下所示:
CREATE OR REPLACE PROCEDURE
test_proc (some_date VARCHAR(10))
RETURNS INT AS
BEGIN
INSERT INTO db.test
-- join TABLE 1 and TABLE 2 for final results
SELECT some_date;
RETURN 1;
END //
DELIMITER ;
但是,我希望 Python 能够读取过程文件,并将存储过程传递给数据库(如果存储过程得到更新但没有手动重新 运行 , 代码拾取程序的重新定义)。
当我将存储过程读入文本流并尝试执行时:
from sqlalchemy import create_engine
conn = create_engine(parameters_to_connect_to_database)
statement = open('stored_procedure.sql').read()
trans = conn.begin()
conn.execute(statement)
trans.commit()
conn.execute(statement)
的语法错误如下:
ProgrammingError: (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 //\nCREATE OR REPLACE PROCEDURE
我知道 sql 脚本实际上没有语法错误,因为如果我在 sql 编辑器软件中,它可以手动运行。如果我将存储过程文件与其中包含 create table 或 insert into 语句的文件交换,则不会返回任何错误并且插入成功。
我如何编辑上面的文件以执行其中包含 SQL 语句的文件,以及其中写入存储过程的文件?
DELIMITER
不是 SQL 语句。它是一个命令,可帮助 MySQL shell 避免混淆关于如何解释 ;
当它出现在存储过程定义中时,存储过程定义本身是 CREATE PROCEDURE 语句的一部分。当 运行 shell 之外的 CREATE PROCEDURE 语句时,DELIMITER
不是必需的(或有效的)。
这失败了:
import sqlalchemy as sa
engine = sa.create_engine("mysql+pymysql://scott:tiger@localhost:3307/mydb")
drop_sp = "DROP PROCEDURE IF EXISTS test_proc"
create_sp = """\
CREATE DEFINER=`root`@`localhost` PROCEDURE `test_proc`()
BEGIN
SELECT 'this is a test';
END //
DELIMITER ;
"""
with engine.begin() as conn:
conn.exec_driver_sql(drop_sp)
conn.exec_driver_sql(create_sp)
但这行得通
import sqlalchemy as sa
engine = sa.create_engine("mysql+pymysql://scott:tiger@localhost:3307/mydb")
drop_sp = "DROP PROCEDURE IF EXISTS test_proc"
create_sp = """\
CREATE DEFINER=`root`@`localhost` PROCEDURE `test_proc`()
BEGIN
SELECT 'this is a test';
END
"""
with engine.begin() as conn:
conn.exec_driver_sql(drop_sp)
conn.exec_driver_sql(create_sp)