Выполнение Pyodbc завершилось неудачей на временной таблице

61
4

У меня есть скрипт Python, который использует библиотеку pyobbc для запуска некоторых запросов, у которых есть планировщик задач, выполняющийся по установленному расписанию. Скрипт работал нормально без проблем на прошлой неделе, и он внезапно столкнулся с ошибкой:

DatabaseError: Execution failed on sql 'select * from #output  ('42S02', "[42S02] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Invalid object name '#output'. (208) (SQLExecDirectW)")

Эта ошибка возникает, когда я пытаюсь извлечь эти данные из запроса с помощью pd.read_sql. Очень странная часть заключается в том, что никаких изменений к сценарию вообще не было. До сегодняшнего дня он работал отлично.

Я исследовал аналогичные проблемы в stackoverflow и попытался использовать те же решения (создание глобальной таблицы temp вместо локальной), и проблема не устранена. Как ни странно, запрос включает в себя две временные таблицы, #data и #output и я могу без проблем получить доступ к содержимому #data с помощью pd.read_sql, но по какой-либо причине попытался использовать тот же метод в другой временной таблице приводит к ошибке выше.

Сам код может быть немного длинным, чтобы включить сюда, но это то, чем он по большей части напоминает (я буду рад поделиться всем, если это не проблема):

connection = pyodbc.connect(...)
cursor = connection.cursor()

query = """create table #data (...)

... #some other commands here in the middle

create table #output (...)

... #two more lines of SQL commands and that it
"""

cursor.execute(query)
totals = pd.read_sql("""select * from #output"""), connection)

Строка cursor.execute(query) не появляется, чтобы генерировать ошибку, поскольку я получаю <pyodbc.Cursor at 0xef2eea0> если я запускаю только эту строку.

Я ценю помощь.

EDIT: Я подозреваю, что сообщение об ошибке связано с тем, что перед оператором create table #output существует часть цикла create table #output и это как-то мешает правильному выполнению следующих команд. Я включил немного более подробно, используя мой примерный код сверху:

connection = pyodbc.connect(...)
cursor = connection.cursor()

query = """create table #data (...)

... #some other commands here in the middle

declare @order int, @limit int, @check varchar(20)
set @order = 1
set @limit = (select count(*) from #data where [weekday] = 'Friday')

while @order <= @limit
begin

update #data
set [order] = @order
where #data.[date] = (select top 1 [date] from #data where [order] is null order by [date] asc)

if (select top 1 [weekday] from #data where [order] is not null order by [date] desc) = 'Friday'
set @order = @order + 1

update #data
set weekly_desc = (select top 1 weekly_desc from #data where [weekday] = 'Friday' and [order] is null order by [date] asc)
where [order] = @order

end

create table #output (...)
"""

cursor.execute(query)
totals = pd.read_sql("""select * from #output""", connection)

спросил(а) 2021-01-27T23:54:00+03:00 2 месяца, 2 недели назад
1
Решение
115

После некоторого дополнительного копания я обнаружил, что после обновления таблицы #data (шаг прямо перед #create table #output..., если у меня был Python, выполните pd.read_sql("""select * from #data""", connection), консоль показала, что последние несколько строк #data содержали значения NaN в столбце order. Я понятия не имею, почему это было так, поскольку выполнение запроса в SQL Server выполняется без проблем. Вероятно, это объясняет, почему он не мог перейти к следующий шаг, который create table #output.

Мой единственный способ заставить его работать снова - переписать часть запроса, в частности часть цикла while, изменив ее из

while @order <= @limit
begin

update #data
set [order] = @order
where #data.[date] = (select top 1 [date] from #data where [order] is null order by [date] asc)

if (select top 1 [weekday] from #data where [order] is not null order by [date] desc) = 'Friday'
set @order = @order + 1

update #data
set weekly_desc = (select top 1 weekly_desc from #data where [weekday] = 'Friday' and [order] is null order by [date] asc)
where [order] = @order

end

в

while @order <= @limit
begin

update #data
set [order] = @order
where #data.[date] = (select top 1 [date] from #data where [order] is null order by [date] asc)

if (select top 1 [weekday] from #data where [order] is not null order by [date] desc) = 'Friday'
set @order = @order + 1

end

update #data
set weekly_desc = t.weekly_desc
from (select [order], weekly_desc
from #data
where weekly_desc is not null
) as t
where #data.weekly_desc is null
and #data.[order] = t.[order]

После этого create table #output и другие команды, и я смог запустить весь скрипт без проблем. Надеясь, он не загадочно перестанет работать снова.

Спасибо за вашу помощь!

ответил(а) 2021-01-27T23:54:00+03:00 2 месяца, 2 недели назад
Ваш ответ
Введите минимум 50 символов
Чтобы , пожалуйста,
Выберите тему жалобы:

Другая проблема