简体   繁体   English

从 PYTHON 调用时,MySQL 存储过程 DELETE 不起作用

[英]MySQL Stored Procedure DELETE not working when called from PYTHON

I have a MySQL stored proc that will back up database records from a beyond a specified INTERVAL to a csv file, then DELETE the same records.我有一个 MySQL 存储过程,它将数据库记录从指定的 INTERVAL 备份到 csv 文件,然后删除相同的记录。

When I call the procedure from phpMyAdmin or MySQL Workbench it works perfect.当我从 phpMyAdmin 或 MySQL Workbench 调用程序时,它运行良好。 It creates the archive file, and deletes the records.它创建存档文件,并删除记录。

However, when I call the stored procedure from within my Python application, it will create the archive file, but does not delete the records.但是,当我从 Python 应用程序中调用存储过程时,它将创建存档文件,但不会删除记录。

The input and session variables are also output to specific log files for debugging. input 和 session 变量也是 output 到特定的日志文件进行调试。 This all works fine and I see what I expect in the log files.这一切都很好,我在日志文件中看到了我的期望。

Here is my stored proc:这是我的存储过程:

CREATE DEFINER=`ctuser`@`%` PROCEDURE `sp_TableDump`(
    IN db VARCHAR(50), 
    IN tbl VARCHAR(50),
    IN dateCol VARCHAR(20),
    IN intrvl VARCHAR(20),
    IN allowArchive boolean,
    IN allowPurge boolean
)
BEGIN
    #I know my input fields are correct because of the log1.log created below
    SELECT db, tbl, dateCol, intrvl, allowArchive, allowPurge into outfile '/var/lib/mysql-files/log1.log';

    SET @defMaxLength = (SELECT @@group_concat_max_len);#get the default group_concat limit    
    SET SESSION group_concat_max_len = 1000000;#set the Group Concat Max Limit for tables with a lot of columns

    SET @date = CURDATE();
    SET @path = CONCAT('/var/lib/mysql-files/', db, '.', tbl, '_ARCHIVE_', @date, '.csv');

    SET @tbl = CONCAT(db, '.', tbl);  

    SET @where = CONCAT(' WHERE ', dateCol, ' < CURDATE() - INTERVAL ', intrvl);
    SET @orderBy = CONCAT(' ORDER BY ', dateCol); 

    #I know my session variables are correct because of the log2.log created below
    SELECT @date, @path, @tbl, @where, @orderBy into outfile '/var/lib/mysql-files/log2.log';

    IF allowArchive THEN    
        #I know we get in here because log2.log gets created            
        #archive the records
        #get the columns from the table
        SET @cols = (SELECT GROUP_CONCAT(QUOTE(`column_name`)) AS columns FROM information_schema.columns WHERE table_schema = db AND table_name = tbl);
        SET @colQry = CONCAT('(SELECT ', @cols, ')');      
        SET @outfileQry = CONCAT('(SELECT * FROM ', @tbl, @where, @orderBy, ' INTO OUTFILE \'', @path, 
                                '\' FIELDS ENCLOSED BY \'\\\'\' TERMINATED BY \'\t\' ESCAPED BY \'\' LINES TERMINATED BY \'\n\')');

        SET @outfileSQL = CONCAT(@colQry, ' UNION ALL ', @outfileQry);
        SELECT @cols, @colQry, @outfileQry, @outfileSQL into outfile '/var/lib/mysql-files/log2.log';

        PREPARE outStmt FROM @outfileSQL;
        EXECUTE outStmt;#This works every time 
        DEALLOCATE PREPARE outStmt;
    END IF;

    IF allowPurge THEN    
        #I know we get in here because log3.log gets created
        #delete the records
        SET @delSQL = CONCAT('DELETE FROM ', @tbl, @where);

        SELECT @delSQL into outfile '/var/lib/mysql-files/log3.log'; # @delSQL looks correct in log3.log

        PREPARE delStmt FROM @delSQL;        
        EXECUTE delStmt; # This does not seem to happen when I run in Python.  It works perfectly in MySQL Workbench or phpMyAdmin
        DEALLOCATE PREPARE delStmt;
    END IF;

    SET SESSION group_concat_max_len = @defMaxLength;#reset the default group_concat limit
END

Here is the Python function:这是 Python function:

def archiveAndDeleteRecords():
    log.info('Attempting to purge data older than ' + interval + ' from ' + db + '.' + tbl + " col: " + columnName)    
    dateTime = datetime.now().strftime("%Y%m%d%H%M%S")
    archivePath = "/mnt/Storage/DatabasePurge/" + db + "/"

    try:
        args = [db, tbl, columnName, interval, allowArchive, allowPurge] # The args look good in python and when passed to stored proc
        stProc = 'sp_TEST'
        log.info('calling stproc ' + stProc)
        log.info('args ' + str(args))
        result_args = cursor.callproc(stProc, args)
        conn.commit()
    except Exception as ex:
        log.error("Could not execute stored procedure!");
        log.error("error: " + str(sys.exc_info()[0]));
        log.error("exception: " + str(ex));
        traceback.print_tb(ex.__traceback__)

    return;

I have been pounding my head against the wall for hours with this.几个小时以来,我一直在用头撞墙。 Any help would be appreciated.任何帮助,将不胜感激。 Thanks.谢谢。

This was also a headache for me, but I found a solution.这对我来说也很头疼,但我找到了解决方案。 On the one hand, your stored procedure has to work in your database.一方面,您的存储过程必须在您的数据库中运行。 On the other hand, in python you will use sqlalchemy to connect to the corresponding database.另一方面,在 python 中,您将使用 sqlalchemy 连接到相应的数据库。 NOTE: update the variable for your corresponding values.注意:更新相应值的变量。

from sqlalchemy import create_engine

driver='ODBC Driver 17 for SQL Server'
engine = create_engine('mssql+pyodbc://{}:{}@{}/{}?driver={}'.format(user_name, password, server_name, database_name, driver))

query = ('exec name_stored_procedure @var1=\'{}\', @var2=\'{}\''.format(value1, value2))

with engine.begin() as conn:
    conn.execute(query)

Using the begin method will execute the stored procedure and commit it to the database, deleting the data you desire使用 begin 方法将执行存储过程并将其提交到数据库,删除您想要的数据

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 SQL 服务器:从 python 调用时存储过程不起作用 - SQL Server: stored procedure not working when called from python 使用os.system()或subprocess.Popen()从Python调用时,为什么我的MySQL存储过程未执行? - Why is my MySQL stored procedure not executing when called from Python using os.system() or subprocess.Popen()? 从无人值守的 Python 调用 MySQL 存储过程 - Call a MySQL stored procedure from Python unattended 如何从python在mysql中创建存储过程? - How can i create Stored procedure in mysql from python? 使用MySQLdb从Python中获取MySQL存储过程的返回值 - Getting return values from a MySQL stored procedure in Python, using MySQLdb 为什么从 sqlalchemy 调用的存储过程不工作,但从工作台调用是工作? - why the stored procedure called from sqlalchemy is not working but calling from workbench is working? 为什么在存储过程中“插入”不能从 python 工作? - Why is "insert into" inside stored procedure not working from python? 从 python 执行存储过程时出现“'where 子句'中的未知列” - “Unknown column in 'where clause'” when executing stored procedure from python Python DataError来自存储过程,但是手动运行时没有错误 - Python DataError coming from stored procedure, but no error when run manually 从Python执行存储过程 - Executing A stored Procedure From Python
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM