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

1 人关注

我在文件 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语句的文件,以及包含有存储过程的文件?

4 个评论
你是否试图执行一个SP,然后执行一个SQL查询?
该存储过程是一个带有日期参数的插入语句本身。我需要通过日期迭代来加载一个表。
语法错误是什么?以及什么是 full 文件的文本( statement 的值)?
@Charlieface - 更新了一些细节
python
mysql
stored-procedures
sqlalchemy
singlestore
Lisle
Lisle
发布于 2022-03-11
1 个回答
Gord Thompson
Gord Thompson
发布于 2022-03-11
已采纳
0 人赞同

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)

but this works

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';