pandas / sqlalchemy / pyodbc:当SELECT

时间:2018-12-17 16:24:04

标签: python sql-server pandas sqlalchemy pyodbc

我正在使用SQL Server 2014,pandas 0.23.4,sqlalchemy 1.2.11,pyodbc 4.0.24和Python 3.7.0。我有一个非常简单的存储过程,该过程对表执行UPDATE,然后对其执行SELECT:

CREATE PROCEDURE my_proc_1
    @v2     INT
AS
BEGIN
    UPDATE my_table_1 
    SET v2 = @v2 
    ;

    SELECT * from my_table_1
    ;
END 
GO

这在MS SQL Server Management Studio中运行良好。但是,当我尝试使用以下代码通过Python调用它时:

import pandas as pd
from sqlalchemy import create_engine

if __name__ == "__main__":
    conn_str = 'mssql+pyodbc://@MODEL_TESTING'
    engine = create_engine(conn_str)
    with engine.connect() as conn:
        df = pd.read_sql_query("EXEC my_proc_1 33", conn)
        print(df)

我收到以下错误:

  

sqlalchemy.exc.ResourceClosedError:此结果对象不返回   行。它已自动关闭。

(请告诉我您是否要进行完整的堆栈跟踪,如果需要,我会进行更新)

当我从存储的proc中删除UPDATE时,代码运行并返回结果。还要注意的是,从除了要更新的表之外的表中进行选择并没有什么不同,我得到了相同的错误。非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

问题是UPDATE语句返回的行数是标量值,而SELECT语句返回的行被“塞住”了行数的后面,pyodbc无法“看到”它们(没有其他伪造)

一种最佳实践是确保我们的存储过程始终以SET NOCOUNT ON;语句开头,以禁止从DML语句(UPDATE,DELETE等)返回行计数值,并允许该存储过程只需返回SELECT语句中的行即可。