通过 SQLAlchemy 将存储过程定义传递给 singlestore/memsql



我在文件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 编辑器软件中,它可以手动运行正常。如果我将存储过程文件与包含创建表或插入语句的文件交换,则不会返回任何错误,并且插入会成功。

如何编辑上述内容以执行包含 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)

最新更新