Ошибка [HY010] [Microsoft][ODBC Driver 13 for SQL Server]Function sequence error (0) (SQLFetch) при записи в файл
Делаю выгрузку из БД (диалект Microsoft SQL Server).
Программа запускается на сервере под Линуксом, ресурс оперативной памяти ограничен.
Поэтому использую функцию pd.read_sql_query() c параметром chunksize.
Порядок действий:
Подключиться к БД и получить объект Iterator[DataFrame]
@time_of_function def _get_chunks_iterator(url_object: URL, query: text, chunk_size: int = 10000) -> Iterator[DataFrame]: engine = create_engine(url_object) with engine.connect() as cnxn: return read_sql_query(query, cnxn, chunksize=chunk_size)
Из полученного итератора перебрать все датафреймы и записать в файл
одной из фукнций (в зависимости от переданного формата).
Excel:
@time_of_function def _make_xl_out_of_iterator(chunks_iterator: Iterator[DataFrame], path: str) -> None: with ExcelWriter(path, engine="openpyxl", mode='w') as writer: chunk = next(chunks_iterator) chunk.to_excel(writer, index=False, engine='openpyxl') # первую строку займут заголовки # строка len(chunk) + 1 будет последней непустой # строка len(chunk) + 2 будет первой свободной для записи first_empty_line = chunk.shape[0] + 2 for chunk in chunks_iterator: update_spreadsheet(path, chunk, starcol=1, startrow=first_empty_line) first_empty_line += chunk.shape[0]
CSV:
@time_of_function def _make_csv_out_of_iterator(chunks_iterator: Iterator[DataFrame], path: str) -> None: with open(path, 'w') as f_out: next(chunks_iterator).to_csv(f_out, index=False) # запись первого чанка с названием столбцов for chunk in chunks_iterator: chunk.to_csv(f_out, index=False, header=False) # пропускаем запись названий столбцов
Где возникает ошибка?
Функция _get_chunks_iterator() отрабатывает без вызова ошибок.
Но при вызове одной одной из функций пункта (2) возникает ошибка с таким трейсбеком:
Traceback (most recent call last):
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\sqlalchemy\engine\cursor.py", line 1138, in fetchmany
l = dbapi_cursor.fetchmany(size)
pyodbc.Error: ('HY010', '[HY010] [Microsoft][ODBC Driver 13 for SQL Server]Function sequence error (0) (SQLFetch)')
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\auxiliary\df_itarator_to_excel.py", line 324, in <module>
prepare_report_file(sql3, absolute_path=CSV_REPORT_PATH, file_format='csv')
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\auxiliary\df_itarator_to_excel.py", line 28, in wrapper
res = function(*args, **kwargs)
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\auxiliary\df_itarator_to_excel.py", line 188, in prepare_report_file
_make_csv_out_of_iterator(chunks_iter, absolute_path)
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\auxiliary\df_itarator_to_excel.py", line 28, in wrapper
res = function(*args, **kwargs)
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\auxiliary\df_itarator_to_excel.py", line 173, in _make_csv_out_of_iterator
next(chunks_iterator).to_csv(f_out, index=False) # запись первого чанка с названием столбцов
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\pandas\io\sql.py", line 1480, in _query_iterator
data = result.fetchmany(chunksize)
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\sqlalchemy\engine\result.py", line 1346, in fetchmany
return self._manyrow_getter(self, size)
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\sqlalchemy\engine\result.py", line 697, in manyrows
rows: List[_InterimRowType[Any]] = self._fetchmany_impl(num)
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\sqlalchemy\engine\cursor.py", line 2107, in _fetchmany_impl
return self.cursor_strategy.fetchmany(self, self.cursor, size)
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\sqlalchemy\engine\cursor.py", line 1144, in fetchmany
self.handle_exception(result, dbapi_cursor, e)
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\sqlalchemy\engine\cursor.py", line 1097, in handle_exception
result.connection._handle_dbapi_exception(
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\sqlalchemy\engine\base.py", line 2326, in _handle_dbapi_exception
raise sqlalchemy_exception.with_traceback(exc_info[2]) from e
File "C:\Users\U_M1GT7\SHELTER\AAProjects\ossktb-rcsite-reporter-api\venv\lib\site-packages\sqlalchemy\engine\cursor.py", line 1138, in fetchmany
l = dbapi_cursor.fetchmany(size)
sqlalchemy.exc.DBAPIError: (pyodbc.Error) ('HY010', '[HY010] [Microsoft][ODBC Driver 13 for SQL Server]Function sequence error (0) (SQLFetch)')
(Background on this error at: https://sqlalche.me/e/20/dbapi)
Process finished with exit code 1
Всё ломается, когда пытаюсь применить функцию next() к полученному итератору.
Вопросы:
- Корректно ли я получаю данные из БД, разбивая на чанки?
- Что может приводить к ошибке Function sequence error (0) (SQLFetch)?
- Как её исправить?
P.S.
Я нашёл такое решение: https://issuehint.com/issue/groveco/django-sql-explorer/423
Но я не понимаю, подходит ли оно мне и как его использовать (где менять эти значения на False)
Прошу подсказать, спасибо за любую помощь.