Python: запись большого объема данных (200K recs) в существующий файл Excel (xlsx)

#python #python-3.x #excel #xlsx

#python #python-3.x #excel #xlsx

Вопрос:

У меня есть требование записать более 200 тыс. записей в существующий файл Excel (xlsx). В файле Excel есть несколько обозначенных строк заголовка, и мне нужно написать после этого. Иногда мне может потребоваться добавить строки в существующий файл Excel, в котором уже есть несколько строк данных.

Данные существуют в локальной базе данных sqlite, я запускаю sql-запрос для извлечения данных (я использую функции плотного ранжирования и разделения в SQL для упрощения обработки).

В настоящее время я использую openpyxl. Я перебираю каждую строку из курсора sql и записываю данные в каждую ячейку в Excel. Я сохраняю книгу после записи каждых 3000 строк, чтобы не возникало проблем с памятью. Он работает нормально, но занимает около 5 часов. Я пробовал win32com, и это заняло еще больше времени.

Как я могу повысить производительность этого процесса записи данных?

Мой текущий пример кода приведен ниже.

     al_row = al_headerRow
    
    for sql_row in cursor.execute(ALSheet_SQL_Select):
        al_row = al_row   1
        al_col = 0

        #Loop thru all the fields in the sheet
        #Seq in AL Sheet and Mapping sheet should match
        for al_field in dictMappingDoc[ALSheet]:
            al_col = al_col   1
            #SQL Cursor output will be retrieved like a list, first element index is 0, hence excel col 1 will be SQL list index 0.
            al_col_sql = al_col - 1
            
            ws.cell(row=al_row,column=al_col).value = sql_row[al_col_sql]
        #End - for - al_field in dictMappingDoc[ALSheet]

        #Interim save to clear memory
        save_counter = save_counter   1
        if save_counter == 3000:
            wb.save(filename = TempFilePath)
            sleep(5)
            save_counter = 0
        #End - if
    #End - for - SQL Row
    
#---- Final Save -----
wb.save(filename = TempFilePath)
sleep(10)
wb.close()
  

Комментарии:

1. Рассматривали ли вы возможность сделать это с помощью C ? Здесь библиотека github.com/troldal/OpenXLSX это могло бы вам помочь.

2. Привет, спасибо. Мне нужно использовать python. Потому что это часть приложения, которое я создаю.

3. Вы можете попытаться создать файл, используя базовый формат XML (см. msdn.microsoft.com/en-us/library/dd922181.aspx для получения технических характеристик). Производительность должна быть намного выше за счет отказа от использования библиотеки с проверкой ошибок и необходимости самостоятельно обновлять выходные данные на основе изменений спецификации (очень редко).

4. Вы также можете подумать о pandas для записи в файл Excel. pandas.pydata.org/pandas-docs/stable/reference/api /…

5. Спасибо @VenkataramanR, но с функцией ExcelWriter я получаю ошибку pylint. Абстрактный класс ‘ExcelWriter’ с абстрактными методами, созданными pylint(abstract-class-instantated)

Ответ №1:

Как предложил Venkataraman R, используйте pandas . Я работаю с более чем 1,3 млн. записей в файле Excel, и для анализа требуется всего несколько секунд.

1 / прочитайте существующий файл Excel в dataframe

2 / Используйте цикл курсора sql для обновления фрейма данных, используя loc, iloc или любой другой, который вам подходит: df.loc[df['column_name'] == some_value_you got_from_sql] всякий раз, когда вам нужно добавить новую строку, просто добавьте ее во временный фрейм данных, который вы добавите в конце

3 / напишите свой файл Excel

Комментарии:

1. Спасибо @Myrt . Я могу напрямую назначить вывод sql в качестве фрейма данных, например df = pd.DataFrame(cursor.execute(ALSheet_SQL_Select)) , его запись в соответствии с требованиями к макету, но создать новый файл и записать его. Для записи в существующий файл я должен инициализировать ExcelWriter. Для ExcelWriter я получаю эту ошибку «Абстрактный класс ‘ExcelWriter’ с абстрактными методами, созданными pylint (abstract-class-instantiated)». Есть предложения о том, как это преодолеть?

2. PS: существующий excel — это шаблон, который будет использоваться в качестве входных данных для другого приложения. Он имеет определенную цветовую кодировку, скрытые значения в строках заголовка, которые я не должен изменять. Я должен просто добавить в тот же файл после строки заголовка.