pandas / sqlalchemy / pyodbc: объект Result не возвращает строки из хранимых процедур, когда инструкция UPDATE появляется перед SELECT - PullRequest
0 голосов
/ 17 декабря 2018

Я использую SQL Server 2014, pandas 0.23.4, sqlalchemy 1.2.11, pyodbc 4.0.24 и Python 3.7.0.У меня есть очень простая хранимая процедура, которая выполняет ОБНОВЛЕНИЕ для таблицы и затем 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: Этот объект результата не возвращаетстрок.Он был закрыт автоматически.

(Пожалуйста, дайте мне знать, если вы хотите полную трассировку стека, я буду обновлять, если так)

Когда я удаляю ОБНОВЛЕНИЕ из сохраненного процесса,код выполняется и результаты возвращаются.Также обратите внимание, что выбор из таблицы, отличной от обновляемой, не имеет значения, я получаю ту же ошибку.Любая помощь очень ценится.

1 Ответ

0 голосов
/ 17 декабря 2018

Проблема в том, что оператор UPDATE возвращает счетчик строк, который является скалярным значением, а строки, возвращаемые оператором SELECT, «застряли» за счетчиком строк, где pyodbc не может их «увидеть» (без дополнительных обработок).

Рекомендуется, чтобы наши хранимые процедуры всегда начинались с оператора SET NOCOUNT ON;, чтобы подавить возврат значений счетчика строк из операторов DML (UPDATE, DELETE и т. Д.) И разрешить хранимыепроцедура, чтобы просто вернуть строки из оператора SELECT.

...