Прежде всего, я попробовал писать прямо в блоб. Но это не сработало. Итак, я попробовал записать во временный каталог, а затем переместить файл в нужный каталог. Даже это не сработало. Я ищу решение для записи Excel с несколькими листами в Azure Blob.
filename = os.path.join(arg_dict['out_dir'], old_attribute_file_path.replace(old_attribute_file_path.split('/')[-1].split('-')[-1].split('.')[0], attribute_files[0].split('-')[1]))
temp_file_name = os.path.join(TMP_PATH, old_attribute_file_path.replace(old_attribute_file_path.split('/')[-1].split('-')[-1].split('.')[0], attribute_files[0].split('-')[1]))
fill_color = PatternFill(start_color='FFFF00', end_color='FFFF00', fill_type='solid')
# Write DataFrames to Excel
with pd.ExcelWriter(temp_file_name, engine='openpyxl') as writer:
df1.to_excel(writer, index=False, sheet_name='Sheet1')
df2.to_excel(writer, index=False, sheet_name='Sheet2')
# Load the workbook
workbook = writer.book
# Save the workbook
workbook.save(temp_file_name)
shutil.move(temp_file_name, filename)
Ошибка, которую я получаю ->
File /local_disk0/.ephemeral_nfs/envs/pythonEnv-6a81eac8-0226-477b-9715-070566214b43/lib/python3.10/site-packages/openpyxl/writer/excel.py:294, in save_workbook(workbook, filename)
292 workbook.properties.modified = datetime.datetime.utcnow()
293 writer = ExcelWriter(workbook, archive)
--> 294 writer.save()
295 return True
File /local_disk0/.ephemeral_nfs/envs/pythonEnv-6a81eac8-0226-477b-9715-070566214b43/lib/python3.10/site-packages/openpyxl/writer/excel.py:275, in ExcelWriter.save(self)
273 def save(self):
274 """Write data into the archive."""
--> 275 self.write_data()
276 self._archive.close()
File /local_disk0/.ephemeral_nfs/envs/pythonEnv-6a81eac8-0226-477b-9715-070566214b43/lib/python3.10/site-packages/openpyxl/writer/excel.py:60, in ExcelWriter.write_data(self)
57 archive = self._archive
59 props = ExtendedProperties()
---> 60 archive.writestr(ARC_APP, tostring(props.to_tree()))
62 archive.writestr(ARC_CORE, tostring(self.workbook.properties.to_tree()))
63 if self.workbook.loaded_theme:
File /usr/lib/python3.10/zipfile.py:1816, in ZipFile.writestr(self, zinfo_or_arcname, data, compress_type, compresslevel)
1814 zinfo.file_size = len(data) # Uncompressed size
1815 with self._lock:
-> 1816 with self.open(zinfo, mode='w') as dest:
1817 dest.write(data)
File /usr/lib/python3.10/zipfile.py:1182, in _ZipWriteFile.close(self)
1180 self._fileobj.seek(self._zinfo.header_offset)
1181 self._fileobj.write(self._zinfo.FileHeader(self._zip64))
-> 1182 self._fileobj.seek(self._zipfile.start_dir)
1184 # Successfully written: Add file to our caches
1185 self._zipfile.filelist.append(self._zinfo)
OSError: [Errno 95] Operation not supported
В кадрах данных PySpark отсутствует метод to_excel
, а блоки данных не позволяют преобразовывать кадры данных PySpark в файлы Excel.
Решение — сохранить файл в databricks/drivers
. Затем переместите файл и удалите его из драйверов.
with pd.ExcelWriter(r'export2.xlsx', engine = "openpyxl") as writer:
#file will be written to /databricks/driver/ i.e., local file system
data.to_excel(writer, index=False, sheet_name='Sheet1')
data2.to_excel(writer, index=False, sheet_name='Sheet2')
workbook = writer.book
# Save the workbook
workbook.save('export2.xlsx')
Здесь вы можете увидеть файл, сохраненный в папке драйверов:
Затем переместите файл из драйверов в папки DBFS:
from shutil import move
move('/databricks/driver/export2.xlsx','/dbfs/export2.xlsx')
openpyxl и xlsxwriter используются для фреймов данных pandas. Вы можете использовать плагин spark для записи Excel непосредственно в хранилище BLOB-объектов.
Вы можете установить это на уровне кластера вот так
И ваш код будет выглядеть так. Сначала получите ключ доступа и установите его как конфигурацию искры.
spark.conf.set(
"fs.azure.account.key.<storage_name>.dfs.core.windows.net",
dbutils.secrets.get(scope=<scope_name>, key=<access_key>))
Затем установите путь и запишите свои фреймы данных Spark по тому же пути, но на разных листах.
path = "abfss://<container_name>@<storage_name>.dfs.core.windows.net/testdir/test.xlsx"
spark_Df1.write.format("com.crealytics.spark.excel")\
.option("header", "true")\
.option("dataAddress", "'My Sheet1'!A1")\
.mode("append")\
.save(path)
spark_Df2.write.format("com.crealytics.spark.excel")\
.option("header", "true")\
.option("dataAddress", "'My Sheet2'!A1")\
.mode("append")\
.save(path)
У меня это почему-то не сработало. Однако я нашел решение. Вместо записи файла в dbfs/tmp работала запись в /tmp и последующее перемещение файла в Azure Blob.