Problem:
Masz dostępne Databricks, Pythona i Azure Storage Account. Potrzebujesz pobrać plik z Azure Storage account przy pomocy Pythona w formacie binarnym. Jeżeli chcesz zrobić to przy użyciu Sparka, albo Pandas to nie jest to zadanie.
Dane masz pobrać z pliku binarnego.
Trzeba użyć modułów Pythona do wczytywania plików.
W dokumentacji piszą, że taka operacja jest "not supported". (Stan na 15.10.2024)
Nie chcesz też robić "mount" zdalnego systemu plików. Taka operacja jest nie polecana przez Databricks.
Rozwiązanie:
W Databricks z Pythona NIE można czytać plików ze zdalnego systemu plików. Można za to czytać pliki z lokalnego file systemu. Obejście problemu przedstawionego powyżej to:
- Przy użyciu dbutils.fs albo %fs skopiować pliki ze zdalnego filesystemu do lokalnego.
- Przeczytać pliki z lokalnego systemu plików przy użyciu Pythona.
Skasować skopiowany plik z lokalnego filesystemu.
Wczytywanie z abfss nie działa
Popatrzmy na dokumentację (stan na 15.10.2024)
Jeżeli masz odpowiednio skonfigurowane połączenie do Azure Storage Account na poziomie clustra wtedy przeczytanie danych w Apach Spark działa bez problemu.
https://learn.microsoft.com/en-us/azure/databricks/files/#work-with-files-in-cloud-object-storage
Ale niestety nie takie jest nasze zadanie. Potrzebujemy dostać się do pliku z poziomu Pythona a to nie jest obsługiwana metoda:
Dla pewności sprawdźmy jeszcze czy to działa:
with open("abfss://landing-zone@nextlevelbi.dfs.core.windows.net/landing-zone/goblet_2024-07-18_13-37-08.csv", "r") as f:
data = f.read()
Tak jak jest napisane w dokumentacji, nie działa. Python potrafi czytać lokalne pliki a nie ze zdalnego katalogu.
Zróbmy to więc inaczej.
Wczytywanie binarnych plików z lokalnego systemu plików
OK, Python nie morze wczytać pliku z Azure Blob File System Storage. Ale może wczytać z lokalnego file systemu Databricks.
Dbutils skopiuje nam dane ze zdalnego do lokalnego file systemu:
source_report_path = "abfss://landing-zone@nextlevelbi.dfs.core.windows.net/landing-zone/goblet_2024-07-18.pbix"
target_report_name = "goblet.pbix"
report_temp_file_location = f"file:/tmp/{target_report_name}"
dbutils.fs.cp(source_report_path, report_temp_file_location, True)
Kluczowa instrukcja to dbutils.fs.cp ona kopiuje dane z Azure do storagu, gdzie
Jest umieszczony cluster.
with open((report_temp_file_location.replace('file:','')), 'rb') as f:
print(type(f))
publish_powerbi_report(group_id, target_report_name, f)
Odczytywanie z lokalnego systemu plików w formie binarnej ma miejsce w pierwszej linijce.
W tym przypadku jeszcze publikuję ten raport do serwisu Power BI. Ale o tym już było w tym wpisie:
https://nextlevelbi.pl/jak-opublikowac-report-w-power-bi-uzywajac-pythona/
Uwagi końcowe
Czy można to zrobić inaczej?
Możesz wykorzystać mount w dbutils, żeby zmapować zdalny katalog na katalog lokalny. Wtedy masz możliwość wczytywania danych. Tylko niestety Databricks nie poleca tej opcji, nie będziemy jej więc wykorzystywać.
Możesz też wykorzystać bibliotekę adlfs. Dzięki niej będziesz mógł podłączyć się do Azure Storage Account i czytać pliki:
https://pypi.org/project/adlfs/
https://stackoverflow.com/questions/78199890/access-to-files-in-data-lake-via-open-method-abfss
Jedną z opcji jest też wykorzystanie Microsoftowej biblioteki:
azure-storage-file-datalake
https://learn.microsoft.com/en-us/azure/storage/blobs/data-lake-storage-directory-file-acl-python?tabs=azure-ad
I o tym będzie w kolejnym wpisie.