pandas 为什么存储过程中的“插入”在python中不起作用?

owfi6suc  于 2023-06-04  发布在  Python
关注(0)|答案(3)|浏览(331)

我在SQL Server中编写了一个存储过程,它传递了4个参数。我想检查第一个参数@table_name,以确保它只使用白名单字符,如果没有,将尝试写入另一个数据库中的表(我有DML权限)。
如果名称好,则工作正常,但如果不好,则Python返回
TypeError:“NoneType”对象不可迭代
(这对我来说是意料之中的,因为没有这样的表),但是它没有写入它应该写入的表,并且表被卡住,直到我关闭程序。
当我使用相同的参数从SSMS运行存储过程时,它工作得很好,并成功地写入日志表。

create_str = "CREATE PROC sp_General_GetAllData (@table_name AS NVARCHAR(MAX),\
              @year AS INT, @month AS INT, @pd AS INT) 
              AS 
              BEGIN 
                  SET NOCOUNT ON; 
                  DECLARE @sql NVARCHAR(MAX) # for later uses
                  IF @table_name LIKE '%[^a-zA-Z0-9_]%' 
                  BEGIN
                  # the 'log' table allows NULLs and the fields are used in other cases
                      INSERT INTO [myDB].[mySchema].[log]
                      VALUES (SUSER_SNAME(), NULL, NULL, NULL, NULL, NULL, 
                              'INVALID TABLE NAME: ' + @table_name, GETDATE()) 
                      RAISERROR ('Bad table name! Contact your friendly DBA for details', 0, 0)
                      RETURN
                  END 
              # do some things if the @table_name is ok...
              END"
cursor = sql_conn.execute(create_str)
cursor.commit()

# calling the SP from python - doesn't write to the log table which gets stuck
query = "{CALL sp_General_GetAllData (?, ?, ?, ?)}"
data = pd.read_sql(query, sql_conn, params=['just*testing', 2019, 7, 2])

# calling the SP from SSMS - works fine
EXEC sp_General_GetAllData 'just*testing', 2019, 7, 2

由于第一个参数中的“*”,因此需要向[myDB].[mySchema].[log]插入一行,只有当我从SSMS调用SP时才会发生这种情况,而不是从python调用。为什么?
解决方案:
幸运的是,我发现问题在于当从python发送对SP的调用时,INSERT INTO子句没有提交,它只是等待提交顺序。解决方案是将auto_commit=True添加到pyodbc.connect()函数

42fyovps

42fyovps1#

我也遇到了同样的问题,但是,在“pyodbc.connect()”中添加“auto_commit=True”并没有解决我的问题。我通过在insert语句后添加以下命令解决了这个问题:

commit
hgtggwj0

hgtggwj02#

试试这个链接。也许你的问题是从你的配置mysql连接。通过使用SqlAlchemy、MySql连接器或其他连接器,默认情况下禁用自动提交。
About MySQLdb conn.autocommit(True), Mika's Answer

u5rb5r59

u5rb5r593#

我正在使用pyodbc + pandas read_sql方法,遇到了这个问题。
对我来说,解决方案是在Python脚本的末尾提交并关闭pyodbc连接。

import pyodbc
conn = pyodbc.connect('your connection details')
df = pd.read_sql("EXEC YOUR_SP", conn)
conn.commit()
conn.close()

相关问题