Wróć do katalogu
Season 16 17 Odcinki 1h 4m 2026

Snowflake & Snowpark Python

Edycja 2026. Dogłębne spojrzenie na główną architekturę Snowflake oraz bibliotekę Snowpark Python. Odkryj, jak korzystać z DataFrames, niestandardowych UDFs, Stored Procedures, pandas on Snowflake oraz natywnego trenowania ML w Data Cloud.

Chmurowe hurtownie danych Nauka o danych
Snowflake & Snowpark Python
Teraz odtwarzane
Click play to start
0:00
0:00
1
Architektura Snowflake
Odkryj podstawową architekturę Snowflake. Ten odcinek wyjaśnia oddzielenie warstwy obliczeniowej od przechowywania danych oraz to, jak Snowflake łączy architektury shared-disk i shared-nothing.
4m 11s
2
Wprowadzenie do Snowpark Python
Dowiedz się, jak Snowpark wprowadza język Python do Twoich danych. Omawiamy abstrakcję DataFrame oraz sposób, w jaki Snowpark tłumaczy kod w języku Python na rozproszony SQL.
3m 34s
3
Nawiązywanie sesji
Dowiedz się, jak bezpiecznie połączyć się ze Snowflake za pomocą Snowpark. Omawiamy konfiguracje Session builder, SSO w zewnętrznej przeglądarce oraz zarządzanie poświadczeniami.
3m 58s
4
Python Worksheets w Snowsight
Odkryj, jak pisać i wykonywać kod Snowpark Python bezpośrednio w interfejsie Snowflake. Pomiń lokalną konfigurację i wykorzystaj preinstalowane pakiety Anaconda.
3m 19s
5
Tworzenie Snowpark DataFrames
Zacznij pracę z główną abstrakcją Snowpark: DataFrame. Dowiedz się, jak odwoływać się do tabel, tworzyć DataFrames z wartości dosłownych i wykorzystywać lazy evaluation.
3m 35s
6
Przekształcanie DataFrames
Opanuj przekształcanie DataFrames w Snowpark. Odkrywamy filtrowanie, wybieranie kolumn, łączenie zbiorów danych i wyzwalanie wykonania za pomocą metod akcji.
3m 45s
7
Wywoływanie funkcji systemowych
Dowiedz się, jak wywoływać potężne, wbudowane funkcje SQL Snowflake bezpośrednio z Twoich Python DataFrames bez przepisywania logiki.
3m 27s
8
pandas on Snowflake: Zmiana paradygmatu
Odkryj, jak uruchamiać standardowy kod pandas na ogromną skalę. Wprowadzamy wtyczkę Modin, która pozwala na natywne wykonywanie pandas wewnątrz Snowflake.
3m 58s
9
pandas on Snowflake: Hybrid Execution
Zanurz się w mechanikę Hybrid Execution w pandas on Snowflake. Dowiedz się, jak silnik płynnie przełącza się między rozproszonymi obliczeniami w chmurze a pamięcią lokalną.
4m 03s
10
Pobieranie danych zewnętrznych
Dowiedz się, jak pobierać dane z systemów zewnętrznych za pomocą Snowpark DB-API i JDBC. Wprowadź dane operacyjne bezpośrednio do swoich potoków analitycznych.
3m 47s
11
Tworzenie skalarnych UDFs
Wprowadź niestandardową logikę w języku Python do swoich zapytań SQL. Ten odcinek omawia tworzenie anonimowych i nazwanych User-Defined Functions (UDFs) w Snowpark.
4m 09s
12
Zarządzanie zależnościami dla UDFs
Dowiedz się, jak importować biblioteki firm trzecich i lokalne moduły do swoich Snowflake UDFs, używając kanału Anaconda i importów w ramach Session.
3m 49s
13
Budowanie User-Defined Table Functions
Wyjdź poza wartości skalarne. Dowiedz się, jak budować User-Defined Table Functions (UDTFs), aby zwracać wiele wierszy i kolumn z pojedynczego wejścia.
3m 53s
14
Tworzenie Stored Procedures
Zautomatyzuj swoje potoki w całości wewnątrz Snowflake. Odkrywamy tworzenie Stored Procedures do wykonywania złożonej logiki biznesowej i przepływu sterowania.
3m 51s
15
Trenowanie modeli ML w Snowflake
Odkryj, jak bezpiecznie trenować ciężkie modele uczenia maszynowego na hurtowniach zoptymalizowanych pod kątem Snowpark, używając niestandardowych Python Stored Procedures.
3m 43s
16
Dynamiczny dostęp do plików z SnowflakeFile
Dowiedz się, jak dynamicznie przesyłać strumieniowo duże, nieustrukturyzowane pliki z internal stages bezpośrednio wewnątrz Twoich UDFs i Stored Procedures.
3m 45s
17
Testowanie Snowpark Python
Upewnij się, że Twoje potoki danych są solidne. Omawiamy konfigurację PyTest, tworzenie fixtur Session oraz testowanie jednostkowe przekształceń DataFrames.
3m 45s

Odcinki

1

Architektura Snowflake

4m 11s

Odkryj podstawową architekturę Snowflake. Ten odcinek wyjaśnia oddzielenie warstwy obliczeniowej od przechowywania danych oraz to, jak Snowflake łączy architektury shared-disk i shared-nothing.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 1 z 17. Największym wąskim gardłem w big data rzadko jest storage. Prawdziwy problem pojawia się, gdy musisz przenosić ogromne zbiory danych przez sieć, tylko po to, by dotrzeć do warstwy compute. Architektura Snowflake całkowicie omija ten problem. Ludzie często zakładają, że Snowflake to po prostu relacyjna baza danych on-premise przeniesiona do chmury w modelu lift and shift, albo tradycyjny klaster Hadoop, którego musisz pilnować. Nie jest ani jednym, ani drugim. Snowflake to w pełni zarządzana usługa, zbudowana natywnie dla chmury. Nie instalujesz oprogramowania. Nie konfigurujesz sprzętu. Cały maintenance, zarządzanie i tuning są robione za ciebie w tle. Aby zrozumieć, jak to osiąga, spójrz na jego hybrydową architekturę. Snowflake łączy architekturę shared-disk z architekturą shared-nothing. W tradycyjnym podejściu shared-disk, wszystkie węzły compute mają dostęp do jednego centralnego repozytorium danych. W architekturze shared-nothing, każdy węzeł compute ma swój własny, lokalny kawałek danych do przetworzenia. Snowflake bierze to, co najlepsze z obu tych rozwiązań. Utrzymuje jedno centralne repozytorium storage, dostępne dla wszystkich węzłów compute, ale wykorzystuje niezależne klastry massively parallel processing do odpalania właściwych zapytań na tych danych. Ten hybrydowy model dzieli się na trzy odrębne warstwy. Pierwsza to warstwa Database Storage. Kiedy ładujesz dane do Snowflake'a, nie wrzuca on po prostu surowych plików do bucketu w chmurze. Reorganizuje te dane w wewnętrzny, zoptymalizowany, skompresowany format kolumnowy. Snowflake zarządza wszystkimi aspektami tego, jak te dane są przechowywane. Nie możesz uzyskać bezpośredniego dostępu do surowego storage'u, wchodzisz z nim w interakcję tylko za pomocą zapytań SQL. Druga warstwa to Query Processing. To tutaj dzieje się cała praca przy użyciu tego, co Snowflake nazywa Virtual Warehouses. Virtual warehouse to po prostu niezależny klaster compute. Ponieważ warstwa compute jest ściśle oddzielona od centralnej warstwy storage, wiele Virtual Warehouses może jednocześnie odpytywać dokładnie te same dane. Nie konkurują o zasoby i nie blokują się nawzajem. I tu jest kluczowa sprawa. Możesz natychmiast skalować moc compute bez przenoszenia ani jednego bajta danych. Weźmy na przykład raport finansowy z końca miesiąca, który wymaga potężnej agregacji danych. Normalnie musiałbyś zmigrować tabele na większy serwer, żeby obsłużyć tak złożony workload. W Snowflake po prostu odpalasz większy virtual warehouse, puszczasz ciężki raport w kilka minut i wyłączasz warehouse, kiedy skończysz. Tabele pod spodem nigdy się nie przemieszczają. Trzecia warstwa, która spaja to wszystko w całość, to Cloud Services. To mózg platformy. To zbiór serwisów, które koordynują wszystko w systemie. Obsługuje uwierzytelnianie użytkowników, zarządza infrastrukturą, parsuje przychodzące zapytania i optymalizuje ścieżki wykonania. Zarządza również metadanymi, śledząc dokładnie, gdzie w warstwie storage znajdują się konkretne fragmenty danych, dzięki czemu zapytania mogą działać wydajnie bez skanowania wszystkiego. Najważniejszy wniosek jest taki, że w Snowflake skalowanie wydajności to tylko przełącznik na klastrze compute, podczas gdy ogromne tabele z danymi pozostają całkowicie nieruchome. Jeśli podoba ci się ta seria i chcesz wesprzeć nasz program, znajdziesz nas, wyszukując DevStoriesEU w serwisie Patreon. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
2

Wprowadzenie do Snowpark Python

3m 34s

Dowiedz się, jak Snowpark wprowadza język Python do Twoich danych. Omawiamy abstrakcję DataFrame oraz sposób, w jaki Snowpark tłumaczy kod w języku Python na rozproszony SQL.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 2 z 17. A co, gdybyś mógł pisać w czystym Pythonie, ale wykonywać go jako hiperzoptymalizowany, rozproszony SQL? Właśnie taką zmianę paradygmatu omawiamy dzisiaj we wprowadzeniu do Snowparka. Tradycyjnie praca z dużymi zbiorami danych w Pythonie oznaczała wyciąganie danych z bazy. Piszesz query, ściągasz dane przez sieć do lokalnej pamięci lub zewnętrznego klastra, uruchamiasz transformacje, a potem wrzucasz wyniki z powrotem. Takie podejście tworzy wąskie gardła w sieci, zwiększa koszty infrastruktury i wprowadza ryzyko bezpieczeństwa, bo przenosisz dane poza kontrolowane środowisko. Snowpark odwraca ten model. Zamiast przenosić dane do compute'a, Snowpark przenosi compute do danych. Częstym błędem jest myślenie, że Snowpark to zewnętrzny silnik przetwarzania. Ludzie często zakładają, że muszą postawić osobny klaster i nim zarządzać, tylko po to, żeby odpalić kod w Pythonie. Wcale tak nie jest. Obliczenia Snowparka działają bezpośrednio wewnątrz Snowflake'a. Używasz dokładnie tych samych virtual warehouses, które wykonują twoje standardowe query SQL. Nie musisz prowizjonować ani utrzymywać żadnej nowej infrastruktury. Kiedy piszesz kod używając API Snowpark Python, wchodzisz w interakcję z obiektem DataFrame. Przypomina to pracę z dobrze znanymi narzędziami do danych w Pythonie. Chainujesz operacje, definiując jak wybierać, filtrować, grupować czy agregować dane. Jednak biblioteka Snowpark nie wykonuje tych operacji lokalnie. Zamiast tego, natywnie tłumaczy twoje operacje na DataFrame'ach w Pythonie na złożone konstrukcje SQL. Następnie Snowflake przetwarza te instrukcje SQL używając swojego standardowego execution engine'u. I tu jest kluczowa sprawa. Snowpark używa lazy evaluation. Kiedy definiujesz swój DataFrame i aplikujesz różne transformacje, żadne dane tak naprawdę się nie przenoszą ani nie zmieniają. API Snowparka po prostu buduje logiczny plan. Zapisuje twoje intencje krok po kroku. Właściwe wykonanie triggeruje się dopiero wtedy, gdy wywołasz konkretną akcję, na przykład poprosisz system o zwrócenie końcowych wyników albo zapisanie ich w nowej tabeli. Ten model lazy evaluation w połączeniu z natywną translacją do SQL drastycznie zmniejsza transfer danych. Wyobraź sobie scenariusz, w którym jesteś data engineerem i masz za zadanie przefiltrować miliard wierszy danych transakcyjnych, żeby wyizolować kilka konkretnych anomalii. Piszesz logikę filtrowania w lokalnym skrypcie w Pythonie. Ponieważ wykonanie jest opóźnione do momentu wywołania akcji, API ma czas na zoptymalizowanie całego chaina operacji i przetłumaczenie go na jedno, wysoce wydajne query SQL. Właściwe filtrowanie odbywa się całkowicie wewnątrz Snowflake'a. Baza danych odwala całą czarną robotę. Jedyne dane, które wędrują przez sieć na twoją lokalną maszynę, to ten końcowy, mały podzbiór anomalii. Właśnie przetworzyłeś miliard wierszy używając składni Pythona, bez pobierania ani jednego surowego rekordu do lokalnej pamięci. Prawdziwą zaletą jest tu zachowanie developer experience natywnego dla Pythona, przy jednoczesnym wykorzystaniu silnika bazy danych do tego, w czym jest najlepszy. Piszesz w Pythonie, ale Snowflake wykonuje SQL. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
3

Nawiązywanie sesji

3m 58s

Dowiedz się, jak bezpiecznie połączyć się ze Snowflake za pomocą Snowpark. Omawiamy konfiguracje Session builder, SSO w zewnętrznej przeglądarce oraz zarządzanie poświadczeniami.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 3 z 17. Boilerplate'y połączeń to często koszmar bezpieczeństwa, pełne hardcodowanych haseł i rozsianych zmiennych środowiskowych. Chcesz dać swojemu zespołowi lokalne narzędzie command line, ale absolutnie nie możesz zaszyć credentials w kodzie. Rozwiązaniem jest czyste zestawienie sesji przy użyciu natywnych funkcji konfiguracyjnych Snowparka. Każdy skrypt Snowpark zaczyna się od utworzenia obiektu Session. To twoje aktywne połączenie ze środowiskiem Snowflake. Enkapsuluje twoją autentykację, docelowy warehouse i twój context. Aby go zbudować, używasz obiektu builder dostępnego w klasie Session. Najbardziej bezpośrednim podejściem jest przekazanie dictionary. Tworzysz dictionary w Pythonie z kluczami dla konta, usera, hasła, roli, bazy danych i warehouse'a. Przekazujesz to dictionary do metody configs w session builderze, a następnie wywołujesz metodę create. Logika płynie prosto z twojego dictionary do backendu Snowflake. Ale hardcodowanie credentials wewnątrz skryptu w Pythonie to ogromne ryzyko bezpieczeństwa, przez co to podejście nie nadaje się do współdzielonych narzędzi. Aby usunąć credentials z kodu, Snowpark polega na standardowym pliku konfiguracyjnym o nazwie connections.toml. Umieszczasz ten plik w roocie projektu albo w ukrytym katalogu snowflake w twoim katalogu home. Plik TOML przechowuje bloki połączeń. Możesz zdefiniować blok default, blok dev i blok prod, każdy z własnymi parametrami połączenia. Oto kluczowa kwestia. Kiedy używasz pliku TOML, twój kod w Pythonie drastycznie się upraszcza. W ogóle nie przekazujesz dictionary. Po prostu wywołujesz metodę get lub create na session builderze. Snowpark automatycznie skanuje standardowe katalogi, znajduje twój plik TOML, czyta blok default i tworzy instancję Session. Jeśli chcesz konkretnego środowiska, przekazujesz nazwę połączenia do metody configs przed utworzeniem Session. Twój kod pozostaje czysty, a credentials zostają bezpiecznie na lokalnej maszynie. Możemy zabezpieczyć nasze narzędzie command line jeszcze bardziej. Nawet z plikiem TOML, możesz nie chcieć, żeby developerzy przechowywali stałe hasła lokalnie. Możesz całkowicie wyeliminować hasła, używając opartego na przeglądarce Single Sign-On. W swoim pliku TOML pomijasz klucz password. Zamiast tego dodajesz klucz o nazwie authenticator i ustawiasz jego wartość na externalbrowser. Kiedy twój skrypt dociera do etapu tworzenia Session, egzekucja pauzuje. Snowpark przechwytuje proces i automatycznie otwiera domyślną przeglądarkę internetową usera. Przekierowuje developera do identity providera twojej organizacji. Developer loguje się normalnie, spełniając wszelkie wymagania MFA. Kiedy identity provider zatwierdzi logowanie, wysyła tymczasowy token autentykacyjny z powrotem na lokalny port, na którym nasłuchuje Snowpark. Skrypt odbiera token, zestawia bezpieczną sesję Snowflake, a egzekucja Pythona zostaje wznowiona. Twoje narzędzie CLI ma teraz w pełni zautentykowany dostęp do Snowflake, bez ani jednego hasła, które kiedykolwiek dotknęłoby twoich plików konfiguracyjnych czy kodu źródłowego. Najbezpieczniejszy credential to ten, który nigdy nie dotyka twojego kodu, a delegowanie autentykacji do przeglądarki sprawia, że twoje lokalne skrypty są bezpieczne i całkowicie skupione na danych. Chciałbym poświęcić chwilę, żeby podziękować ci za słuchanie — to bardzo nam pomaga. Miłego dnia!
4

Python Worksheets w Snowsight

3m 19s

Odkryj, jak pisać i wykonywać kod Snowpark Python bezpośrednio w interfejsie Snowflake. Pomiń lokalną konfigurację i wykorzystaj preinstalowane pakiety Anaconda.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 4 z 17. Chcesz przetestować szybką transformację danych, ale twoje lokalne środowisko Pythona znowu padło. Twoje connection stringi są nieaktualne i właśnie straciłeś dwadzieścia minut na autentykację. A co, gdybyś mógł pisać kod na w pełni skonfigurowanym środowisku bezpośrednio w przeglądarce, bez żadnego setupu? Właśnie ten problem rozwiązują Python Worksheets w Snowsight. Python Worksheets to natywny edytor kodu wbudowany bezpośrednio w webowy interfejs Snowflake. Eliminują one problemy z konfiguracją lokalnego środowiska. Pomyśl o prototypowaniu szybkiego skryptu do czyszczenia danych na żywych danych. Zamiast otwierać IDE i zarządzać credentialsami, otwierasz kartę przeglądarki i od razu zaczynasz pisać kod. Logika egzekucji opiera się na wyznaczonym entry poincie. Nie piszesz luźnego, proceduralnego skryptu. Snowflake potrzebuje konkretnej funkcji, żeby wyzwolić twój kod. Domyślnie jest to handler o nazwie main. Ta funkcja przyjmuje jeden argument, którym jest aktywny obiekt session. Ponieważ jesteś już zalogowany do interfejsu Snowflake, system automatycznie ogarnia autentykację i przekazuje aktywną sesję bezpośrednio do twojej funkcji main. Używasz tej sesji do odczytu tabel, wykonywania zapytań i manipulowania danymi za pomocą standardowych metod Snowpark. Oto kluczowa kwestia dotycząca dependencies. Możesz się spodziewać, że otworzysz terminal i użyjesz pip do instalacji bibliotek, ale Python Worksheets tak nie działają. W ogóle nie używasz pip. Snowflake integruje się natywnie z repozytorium Anaconda. W interfejsie worksheetu znajduje się dedykowane dropdown menu packages. Po prostu wyszukujesz potrzebną bibliotekę, jak pandas czy scikit-learn, wybierasz wersję, a Snowflake natychmiast dostarcza ją do twojego runtime'u. To tyle, jeśli chodzi o inputy i setup. A co z outputami? Twój handler musi zwrócić wartość, a to, jak Snowflake interpretuje tę wartość, konfigurujesz w ustawieniach worksheetu. Głównie wybierasz między dwoma return types: Table lub String. Jeśli ustawisz return type na Table, twoja funkcja main musi zwrócić Snowpark DataFrame. Snowflake bierze ten DataFrame i renderuje go jako czystą, interaktywną siatkę w panelu wyników. To idealne rozwiązanie do inspekcji outputu twojego skryptu do czyszczenia danych. Jeśli ustawisz return type na String, twoja funkcja musi zwrócić skalarną wartość tekstową. Używasz tego, gdy chcesz zwrócić status message, agregat liczbowy zrzutowany na tekst, albo JSON payload. Musisz dostosować swój kod do ustawień worksheetu. Jeśli skonfigurujesz worksheet tak, aby oczekiwał Table, ale twoja funkcja zwróci String, wykonanie zakończy się błędem. Prawdziwa siła Python Worksheets nie tkwi w budowaniu ogromnych, wieloplikowych aplikacji. Chodzi o możliwość walidacji logiki transformacji na danych w skali produkcyjnej w kilka sekund, bezpiecznie i bez jakiejkolwiek konfiguracji lokalnej maszyny. Dzięki za wspólnie spędzony czas. Mam nadzieję, że dowiedziałeś się czegoś nowego.
5

Tworzenie Snowpark DataFrames

3m 35s

Zacznij pracę z główną abstrakcją Snowpark: DataFrame. Dowiedz się, jak odwoływać się do tabel, tworzyć DataFrames z wartości dosłownych i wykorzystywać lazy evaluation.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 5 z 17. Jeśli utworzysz instancję DataFrame reprezentującą miliard wierszy, ile pamięci zużyje ona na twoim laptopie? Prawie zero. Powód sprowadza się do podstawowej mechaniki konstruowania obiektów Snowpark DataFrame. Snowpark DataFrame nie jest kontenerem przechowującym twoje informacje. To po prostu logiczna referencja do danych znajdujących się w Snowflake. Kiedy definiujesz DataFrame w swoim kodzie w Pythonie, tak naprawdę konstruujesz query plan. Opiera się to na koncepcji zwanej lazy evaluation. W ramach lazy evaluation, Snowpark opóźnia wykonanie bazowego kodu SQL, dopóki jawnie nie wywołasz akcji, która wymaga końcowego wyniku. Dopóki ten trigger nie nastąpi, każdy budowany przez ciebie DataFrame to tylko lekki zestaw instrukcji. Podstawowym sposobem na rozpoczęcie budowania tych instrukcji jest metoda session dot table. Przekazujesz nazwę istniejącej tabeli lub widoku w Snowflake jako string. Możesz podać samą nazwę tabeli lub w pełni kwalifikowaną nazwę, zawierającą bazę danych i schemat. Częstym błędem nowych użytkowników jest zakładanie, że wywołanie session dot table pobiera zawartość tabeli do ich lokalnego środowiska Pythona, podobnie jak działa Pandas. Wcale tak nie jest. Jeśli wskażesz session dot table na dziesięcioterabajtowy log transakcyjny, funkcja w Pythonie zwróci wynik w milisekundach. Żadne dane nie są przesyłane przez sieć. Obiekt DataFrame po prostu rejestruje tę konkretną tabelę jako root node twojego execution plan. Innym podejściem jest metoda session dot sql. Używasz jej, gdy chcesz zdefiniować DataFrame przy użyciu surowego stringa SQL. Jest to szczególnie przydatne, jeśli masz już istniejące zapytanie, które chcesz przenieść, lub jeśli wolisz wyrazić konkretną początkową ekstrakcję w SQL. Podobnie jak w przypadku metody table, przekazanie zapytania do session dot sql nie wysyła go do Snowflake w celu natychmiastowego wykonania. Tworzy to DataFrame, który reprezentuje wynik tego konkretnego zapytania. Możesz o tym myśleć jak o definiowaniu widoku inline. Trzecim mechanizmem jest metoda session dot create dataframe. Ta działa inaczej, ponieważ zaczyna od danych, które już siedzą na twojej lokalnej maszynie. Możesz przekazać do tej metody listę z Pythona, słownik lub Pandas DataFrame. Po uruchomieniu, Snowpark bierze te lokalne dane, wgrywa je do Snowflake i umieszcza w tabeli tymczasowej. Następnie metoda zwraca Snowpark DataFrame wskazujący na tę nową tabelę tymczasową. Oto kluczowa sprawa. Ponieważ session dot create dataframe fizycznie przenosi dane z twojej maszyny do Snowflake, jego wydajność zależy całkowicie od rozmiaru twojego lokalnego datasetu i twojego połączenia sieciowego. Używasz tego do wypychania małych tabel lookupowych lub parametrów konfiguracyjnych do Snowflake, aby mogły one współdziałać z twoimi większymi datasetami. Możesz pozwolić, aby Snowpark wywnioskował nazwy kolumn i typy danych z twoich lokalnych obiektów, albo możesz jawnie zdefiniować schemat używając obiektu Snowpark StructType, aby zapewnić precyzję. Za każdym razem, gdy konstruujesz Snowpark DataFrame, niezależnie od metody, definiujesz relację do danych, a nie pobierasz same dane. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
6

Przekształcanie DataFrames

3m 45s

Opanuj przekształcanie DataFrames w Snowpark. Odkrywamy filtrowanie, wybieranie kolumn, łączenie zbiorów danych i wyzwalanie wykonania za pomocą metod akcji.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake & Snowpark Python, odcinek 6 z 17. Piszesz dziesięć złożonych operacji na DataFrame z rzędu, ale system nie uruchamia dziesięciu oddzielnych zapytań. Zamiast tego opóźnia wykonanie i buduje jedno idealnie zoptymalizowane zapytanie SQL pod maską. Dzisiaj porozmawiamy o transformowaniu DataFrame'ów. Kiedy transformujesz DataFrame, tworzysz przepis na to, jak ukształtować twoje dane. Żeby zbudować ten przepis, potrzebujesz niezawodnego sposobu na odwoływanie się do kolumn z danymi. Robisz to za pomocą funkcji o nazwie col. Przekazujesz nazwę kolumny jako string do tej funkcji, a ona zwraca obiekt kolumny. Następnie używasz tego obiektu w innych metodach do budowania wyrażeń, na przykład żeby sprawdzić, czy wartość kolumny jest równa konkretnej liczbie lub stringowi. Spójrzmy na konkretny scenariusz. Masz dwa DataFrame'y. Jeden zawiera profile klientów, a drugi rekordy transakcji. Chcesz zidentyfikować najbardziej wartościowych użytkowników i powiązać ich z ich ostatnimi zakupami. Gdybyś napisał to w czystym SQL-u, mógłbyś skończyć z wielkim, zagnieżdżonym zapytaniem, które zmusza cię do czytania logiki od środka na zewnątrz. W przypadku DataFrame'ów używasz method chaining, żeby zapisać logikę z góry na dół. Najpierw bierzesz DataFrame z klientami i wywołujesz metodę filter. Wewnątrz metody filter używasz funkcji col, żeby wskazać kolumnę z poziomem wydatków i określić, że musi być równa najwyższemu poziomowi. Zaraz po tym filter, chainujesz metodę select. Ponownie używasz funkcji col, żeby określić, że chcesz zostawić tylko ID klienta i adres e-mail. Każda transformacja zwraca nowy DataFrame, co pozwala ci podpiąć kolejną instrukcję bezpośrednio na końcu poprzedniej. Teraz druga część, czyli dorzucenie danych o transakcjach. Wywołujesz metodę join na swoim przefiltrowanym DataFrame z klientami. Przekazujesz DataFrame z transakcjami jako pierwszy argument. Następnie określasz warunek dla joina, na przykład dopasowanie kolumny z ID klienta z obu zbiorów danych. Możesz też zdefiniować typ joina, na przykład inner join albo left join. Logikę czyta się sekwencyjnie. Robisz filter, select i join. Oto kluczowa sprawa. Kiedy Python czyta ten chain metod, Snowpark nie dotyka samych danych. Transformacje są ewaluowane leniwie. DataFrame działa po prostu jak blueprint. Rejestruje każdy filter, select i join, o który poprosisz, ale nie wykonuje ich krok po kroku. To opóźnione wykonanie pozwala frameworkowi spojrzeć na całą sekwencję operacji i zoptymalizować ją, zanim cokolwiek faktycznie się uruchomi. Wykonanie uruchamia się dopiero wtedy, gdy w końcu poprosisz o konkretny wynik. Wymaga to wywołania metody akcji. Jeśli chcesz wypisać małą próbkę danych w terminalu, wywołujesz metodę show. Jeśli chcesz pobrać w pełni przetworzone wyniki z powrotem do lokalnej pamięci Pythona, wywołujesz metodę collect. W momencie wywołania collect, Snowpark tłumaczy twój blueprint na pojedyncze, wydajne zapytanie SQL i wysyła je do Snowflake. Zyskujesz korzyść z pisania czytelnego kodu w Pythonie krok po kroku, podczas gdy silnik bazy danych i tak przetwarza dane w jednym, wysoce zoptymalizowanym przebiegu. To wszystko na dzisiaj. Do usłyszenia następnym razem!
7

Wywoływanie funkcji systemowych

3m 27s

Dowiedz się, jak wywoływać potężne, wbudowane funkcje SQL Snowflake bezpośrednio z Twoich Python DataFrames bez przepisywania logiki.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 7 z 17. Budujesz data pipeline i nagle potrzebujesz złożonej manipulacji na stringach albo jakiejś nietypowej konwersji matematycznej. Nie musisz pisać tej logiki od zera w Pythonie. Baza danych już wie, jak to zrobić. I tu do gry wchodzi Calling System Functions. Snowflake ma setki wbudowanych funkcji systemowych napisanych w mocno zoptymalizowanym C++. Obsługują one wszystko, od parsowania tekstu po obliczanie odchylenia standardowego. Snowpark pozwala ci wywoływać te natywne funkcje SQL bezpośrednio z twojego kodu w Pythonie. Masz do dyspozycji znajomą strukturę Pythona, ale cała czarna robota dzieje się wewnątrz Snowflake. Same dane nigdy nie opuszczają serwera, by być przetwarzane w twoim lokalnym środowisku Pythona. Aby uzyskać do nich dostęp, importujesz moduł snowflake dot snowpark dot functions. Ten moduł zawiera bezpośrednie wrappery w Pythonie dla większości standardowych operacji SQL. Jeśli potrzebujesz przekonwertować tekst na wielkie litery, po prostu wywołujesz funkcję upper z tego modułu i przekazujesz jej obiekt kolumny. Pod spodem Snowpark tłumaczy twój kod w Pythonie na odpowiednią składnię SQL i wypycha go do bazy danych w celu wykonania. To pokrywa większość use case'ów. Ale co się stanie, gdy Snowflake wypuści nową funkcję SQL, albo będziesz musiał użyć specjalistycznej funkcji systemowej, która nie ma jeszcze swojego wrappera w Pythonie w tym module? Nie musisz czekać na kolejny release biblioteki Snowpark, żeby z niej skorzystać. I to jest najważniejsza część. Możesz użyć dedykowanej metody o nazwie call_function, aby wywołać dowolną funkcję systemową Snowflake po jej dokładnej nazwie w SQL-u. Wyobraź sobie scenariusz, w którym masz tabelę z milionami wierszy zawierających pomiary kątów w stopniach, a twój model machine learningowy na dalszym etapie wymaga ich w radianach. Zamiast pisać customową transformację matematyczną w Pythonie, która zaciąga wszystkie te wiersze do pamięci, pozwalasz silnikowi bazy danych wykonać tę pracę. Importujesz call_function. Następnie wywołujesz ją, przekazując string radians jako pierwszy argument. Drugim argumentem jest obiekt kolumny, którą chcesz przekształcić. Snowpark natychmiast robi pushdown tego wywołania jako natywnej operacji SQL radians na całym twoim datasecie. Wykonuje się to z prędkością skompilowanego kodu C++, a tobie zajmuje dokładnie jedną linijkę kodu w Pythonie. Metoda call_function jest elastyczna. Jeśli pod spodem funkcja SQL wymaga wielu inputów, po prostu przekazujesz je po kolei po nazwie funkcji. Te inputy mogą być innymi obiektami kolumn, albo wartościami literalnymi, takimi jak konkretny string czy liczba. Snowpark mapuje twoje argumenty z Pythona bezpośrednio na oczekiwane parametry SQL. Taki design utrzymuje twój kod w czystości, jednocześnie maksymalizując wydajność. Nie tracisz dostępu do surowej mocy natywnych funkcji SQL w Snowflake tylko dlatego, że piszesz w innym języku. Wykorzystując funkcje systemowe, traktujesz Pythona jako orkiestratora, pozwalając silnikowi bazy danych robić dokładnie to, do czego został stworzony. Dzięki za wysłuchanie. Do usłyszenia następnym razem!
8

pandas on Snowflake: Zmiana paradygmatu

3m 58s

Odkryj, jak uruchamiać standardowy kod pandas na ogromną skalę. Wprowadzamy wtyczkę Modin, która pozwala na natywne wykonywanie pandas wewnątrz Snowflake.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 8 z 17. Skalowanie istniejącego pipeline'u w pandas tradycyjnie oznaczało wyrzucenie kodu i przepisywanie wszystkiego w rozproszonym frameworku, takim jak Spark. A co, gdybyś mógł obsłużyć sto razy większy dataset, zmieniając tylko jeden import? To jest właśnie główne założenie pandas on Snowflake. pandas to uniwersalny standard do manipulacji danymi w Pythonie. Jest ekspresyjny, czytelny i głęboko zakorzeniony w tym, jak na co dzień pracują inżynierowie danych i data scientiści. Problem w tym, że pandas jest z natury ograniczony do działania w architekturze single-node. Wymaga, żeby wszystkie twoje dane zmieściły się w pamięci lokalnej. Kiedy twój dataset przerasta możliwości twojego laptopa albo instancji w chmurze, standardowy pandas po prostu się wysypuje. pandas on Snowflake to całkowita zmiana paradygmatu dla takich legacy pipeline'ów. Działa jak narzędzie do migracji typu zero-friction. Załóżmy, że masz gotowy skrypt w Pythonie, który czyści i agreguje codzienne logi transakcji. Działa idealnie na dziesięciu gigabajtach danych, ale nagle musisz przetworzyć cały terabajt. Żeby to wyskalować, wcale nie musisz przepisywać swojej logiki na SQL. Nie musisz nawet uczyć się specyficznej składni standardowego API Snowpark DataFrame. Zmieniasz tylko jedną linijkę na samej górze pliku. Usuwasz standardowy import pandas as pd. Zastępujesz go przez import snowflake.snowpark.modin.pandas as pd. I tu robi się ciekawie. Często pojawia się nieporozumienie co do tego, jak to właściwie przetwarza dane. Wielu developerów zakłada, że to po prostu standardowy pandas działający na aktywnym połączeniu, który pobiera miliony wierszy na lokalną maszynę, żeby je przetworzyć. Nic bardziej mylnego. Kiedy używasz tego konkretnego importu z Modin, żadne dane nie są pobierane na twoją maszynę. Zamiast tego, ta biblioteka przechwytuje każdą komendę pandas, którą napiszesz w swoim skrypcie. Kiedy chainujesz filtrowanie, group-by i agregację średniej, silnik pod spodem tłumaczy dokładnie tę sekwencję na zoptymalizowane query w Snowflake SQL. Transpiluje twoją składnię pandas na SQL, a następnie wysyła ten SQL do compute engine'u Snowflake. Cała operacja wykonuje się w pełni wewnątrz twojego warehouse'u Snowflake. Twoja lokalna maszyna odpowiada tylko za orkiestrację komend. Cały heavy lifting jest rozproszony po klastrach Snowflake. To daje ci dokładnie taki sam developer experience jak w pandas, ale napędzany przez masywnie równoległą bazę danych. Taka zmiana rozwiązuje dwa duże problemy organizacyjne naraz. Po pierwsze, eliminuje problem data egress. Ponieważ operacje są pushowane do bazy danych, twoje surowe dane nigdy nie opuszczają bezpiecznego środowiska Snowflake. Po drugie, oszczędza miesiące na ponowne szkolenie developerów. Twój zespół dalej pisze znajome dataframe'y, joiny i agregacje, które już doskonale zna. Po prostu uruchamia je w chmurze, a nie na swoim lokalnym procesorze. Prawdziwa moc pandas on Snowflake polega na tym, że decoupluje język, którego używasz do opisywania transformacji danych, od silnika, który je faktycznie wykonuje. Jeśli takie techniczne deep dive'y są dla ciebie pomocne, możesz wesprzeć nasz podcast, wyszukując DevStoriesEU na Patreon. To wszystko w tym odcinku. Dzięki za wysłuchanie i keep building!
9

pandas on Snowflake: Hybrid Execution

4m 03s

Zanurz się w mechanikę Hybrid Execution w pandas on Snowflake. Dowiedz się, jak silnik płynnie przełącza się między rozproszonymi obliczeniami w chmurze a pamięcią lokalną.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 9 z 17. Twój kod jest teraz na tyle inteligentny, że dokładnie wie, kiedy wykorzystać pamięć twojego laptopa, a kiedy odpalić cloud cluster. To jest główna koncepcja stojąca za pandas w Snowflake: Hybrid Execution. Kiedy używasz standardowego pandas, każda operacja wykonuje się w pamięci twojej lokalnej maszyny. Jeśli załadujesz ogromny dataset, twój proces po prostu crashuje. Snowpark pandas API rozwiązuje ten problem, mapując twoje komendy pandas na SQL i wykonując je w Snowflake warehouse. Ale nie każda funkcja pandas ma bezpośredni odpowiednik w SQL. Niektóre operacje, takie jak plotowanie czy aplikowanie specyficznych, customowych funkcji w Pythonie, wymagają do działania lokalnej biblioteki pandas. Wyzwaniem jest płynne przełączanie się między cloud engine a twoim środowiskiem lokalnym bez przeciągania gigabajtów surowych danych przez sieć. Hybrid Execution obsługuje to przejście dynamicznie. To execution model zbudowany całkowicie wokół optymalizacji pod kątem jak najniższego kosztu transferu danych. Kiedy odpalasz skrypt używając Snowpark pandas API, silnik działa jak inteligentny router. Jego domyślnym zachowaniem jest trzymanie danych w chmurze. Tłumaczy twój kod na zapytania SQL i wykonuje je używając Snowflake compute. Przejdźmy przez praktyczny scenariusz. Zaczynasz od tabeli zawierającej dziesięć milionów wierszy. Piszesz linijkę kodu, żeby odfiltrować nieprawidłowe rekordy, a następnie grupujesz dane, żeby policzyć średnią. Do tego momentu silnik tłumaczy twoje komendy filtrowania i agregacji bezpośrednio na SQL. Snowflake warehouse odwala czarną robotę. Twoja lokalna maszyna nie pobiera ani jednego wiersza z tego potężnego datasetu. Agregacja redukuje te dziesięć milionów wierszy do tabeli podsumowującej, która ma dokładnie siedem wierszy. W kolejnym kroku piszesz komendę, żeby wyplotować te siedem wierszy na wykresie. Plotowanie jest z natury operacją lokalną. Silnik bazy danych Snowflake nie narysuje za ciebie wykresu. I tu pojawia się kluczowa sprawa. Silnik rozpoznaje, że komenda plot wymaga przejścia do lokalnego backendu pandas. Ponieważ silnik inteligentnie przetwarza twoje operacje, sprawdza stan twoich danych tuż przed wywołaniem lokalnej operacji. Wie, że poprzednia agregacja dała w wyniku tylko siedem wierszy. Więc zamiast przenosić oryginalne dziesięć milionów wierszy na twój laptop, żeby przetworzyć agregację lokalnie, pozwala Snowflake'owi dokończyć matematykę w chmurze. Następnie triggeruje download tylko tych ostatnich siedmiu wierszy do twojej lokalnej pamięci. Kiedy dane dotrą do twojego lokalnego środowiska, standardowy pandas przejmuje stery. Lokalna biblioteka wykonuje komendę plot, używając tych siedmiu wierszy. Wszelkie kolejne operacje, które wykonasz na tej konkretnej strukturze danych, będą nadal działać lokalnie, ponieważ dane przekroczyły już granicę sieci. System izoluje ciężkie manipulacje danymi wewnątrz infrastruktury chmurowej. Odracza transfer sieciowy do momentu, aż operacja będzie bezwzględnie wymagać lokalnego wykonania. Zanim to nastąpi, twoje kroki manipulacji danymi zazwyczaj redukują dataset do ułamka jego pierwotnego rozmiaru. Zachowujesz składnię API, którą już znasz, ale całkowicie unikasz network bottlenecku. Cechą definiującą Hybrid Execution jest nie tylko to, że robi fallback do pamięci lokalnej, ale to, że strategicznie zmniejsza payload w chmurze przed wykonaniem skoku. To wszystko w tym odcinku. Dzięki za wysłuchanie i koduj dalej!
10

Pobieranie danych zewnętrznych

3m 47s

Dowiedz się, jak pobierać dane z systemów zewnętrznych za pomocą Snowpark DB-API i JDBC. Wprowadź dane operacyjne bezpośrednio do swoich potoków analitycznych.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 10 z 17. A co, gdybyś mógł odpytywać bazę danych PostgreSQL z poziomu swojego skryptu w Pythonie na Snowflake? Zazwyczaj przenoszenie danych z operacyjnej bazy danych do Snowflake wymaga zewnętrznego pośrednika. Konfigurujesz narzędzie do ekstrakcji na osobnym serwerze, zarządzasz credentialsami, wrzucasz pliki na stage i planujesz joby, tylko po to, żeby przygotować dane do analizy. Ingestowanie danych zewnętrznych bezpośrednio przez Snowpark Python rozwiązuje ten problem, całkowicie eliminując pośrednika. To podejście pozwala ci uprościć architekturę danych. Wykorzystując external network access w Snowflake, twój kod w Pythonie może komunikować się bezpośrednio z innymi systemami. Możesz użyć standardowych bibliotek Python DB-API lub driverów JDBC, żeby połączyć się z zewnętrznymi bazami danych bezpośrednio ze stored procedure w Snowparku lub z user-defined table function. Weźmy konkretny scenariusz. Masz starszą bazę on-premise PostgreSQL z danymi inwentaryzacyjnymi i musisz zjoinować te dane z live'owymi tabelami klientów w Snowflake. Zamiast stawiać skomplikowany pipeline do ingestu, piszesz stored procedure w Snowpark Python. Wewnątrz tej procedury używasz standardowego connectora Postgres DB-API. Przekazujesz swój connection string, który odwołuje się do credentialsów bezpiecznie zarządzanych przez Snowflake. Otwierasz połączenie, wykonujesz standardowy select w SQL-u na zewnętrznej bazie PostgreSQL i pobierasz result set. Kiedy dane są już w pamięci w twojej funkcji w Pythonie, po prostu robisz yield wierszy z powrotem do Snowflake'a, albo konwertujesz je bezpośrednio na DataFrame w Snowparku. Twoje zewnętrzne dane inwentaryzacyjne są teraz dostępne jako natywny obiekt w Snowflake, gotowe do zjoinowania z tabelami klientów w jednym query. Logika przepływa z zewnętrznego systemu operacyjnego prosto do twojego środowiska analitycznego, bezpiecznie i bez pośrednich serwerów stagingowych. Tyle jeśli chodzi o relacyjne inputy. A co z semi-ustrukturyzowanymi źródłami danych, takimi jak zagnieżdżone pliki wrzucone na stage? Snowpark oferuje również specjalistyczne narzędzia do parsowania złożonych formatów. Doskonałym przykładem jest reader XML RowTag. Kiedy musisz zingestować nieporęczny plik XML, nie musisz pisać customowej logiki parsowania, żeby nawigować po całym drzewie dokumentu. Zamiast tego określasz row tag. To konkretny element XML, który reprezentuje pojedynczy rekord. Wywołujesz metodę read na swojej sesji Snowpark, ustawiasz format na XML i podajesz parametr row tag. Snowflake skanuje dokument, identyfikuje każde wystąpienie tego tagu i wyodrębnia je jako pojedynczy wiersz w DataFrame. Złożona hierarchia powyżej i poniżej tego tagu jest spłaszczana lub pakowana w kolumny, w zależności od twojego schematu. W jednym kroku zamienia to zagnieżdżony dokument tekstowy w czystą tabelę gotową do odpytywania. I tu jest sedno sprawy. Niezależnie od tego, czy otwierasz połączenie JDBC do bardzo starej bazy on-premise, czy kierujesz reader row tagów na zagnieżdżony plik XML, konsolidujesz swoją logikę ingestu wewnątrz platformy danych. Zamieniasz problemy integracyjne w proste problemy z wykonywaniem kodu. Dzięki za wysłuchanie. Do usłyszenia następnym razem!
11

Tworzenie skalarnych UDFs

4m 09s

Wprowadź niestandardową logikę w języku Python do swoich zapytań SQL. Ten odcinek omawia tworzenie anonimowych i nazwanych User-Defined Functions (UDFs) w Snowpark.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 11 z 17. Jak uruchomić customową logikę parsowania stringów w Pythonie na miliardach wierszy bez przenoszenia danych? Odpowiedź leży w tworzeniu skalarnych UDF-ów, czyli User-Defined Functions. Standardowe funkcje SQL pokrywają większość codziennych transformacji danych. Gdy standardowy SQL nie wystarcza, pythonowe UDF-y płynnie wkraczają do akcji. Jeśli masz do czynienia z mocno customowymi regułami, jak pisanie złożonego wyrażenia regularnego do parsowania brudnych adresów e-mail, czysty SQL szybko staje się nieczytelny lub wręcz niemożliwy do napisania. Skalarne UDF-y rozwiązują ten problem, pozwalając ci pisać zwykłą logikę w Pythonie i wykonywać ją natywnie wewnątrz compute engine'u Snowflake'a. Funkcja skalarna po prostu przetwarza jeden wiersz wejściowy i zwraca dokładnie jedną wartość wyjściową. Aby zdeployować swój kod w Pythonie, używasz Snowparka do zarejestrowania funkcji. Jeśli potrzebujesz tej logiki tylko dla bieżącego skryptu, tworzysz anonimowego UDF-a. Najprostszym sposobem, żeby to osiągnąć, jest użycie dekoratora at-UDF. Najpierw piszesz standardową funkcję w Pythonie. Nazwijmy ją extract email domain. Wewnątrz niej używasz standardowego modułu regex z Pythona do parsowania stringa i zwrócenia dopasowanej domeny. Tuż nad definicją funkcji umieszczasz dekorator at-UDF. Kiedy twój skrypt się wykonuje, Snowpark automatycznie serializuje tę funkcję, pushuje ją na serwer i zwraca referencję do obiektu UDF. Możesz teraz przekazać ten obiekt do operacji na kolumnach DataFrame'a, aplikując swój customowy parser na ogromnych tabelach, tak jakby był natywną funkcjonalnością bazy danych. Alternatywnie, możesz pominąć dekorator i przekazać swoją funkcję jawnie do metody session dot udf dot register. Obie metody tworzą tymczasowy obiekt w silniku bazy danych. W momencie zamknięcia twojej sesji Snowpark, anonimowy UDF jest całkowicie dropowany. I tu zaczyna się robić ciekawie. Jeśli twoja nowa logika parsowania jest wartościowa, prawdopodobnie chcesz udostępnić ją innym użytkownikom lub przekazać do downstreamowych pipeline'ów SQL. Aby to osiągnąć, tworzysz nazwanego, permanentnego UDF-a. Używając tej samej metody register, dodajesz flagę is permanent ustawioną na true i podajesz wartość typu string dla parametru name. Ta nazwa określa, jak funkcja będzie wywoływana w bazie danych. Kiedy robisz UDF-a permanentnym, Snowflake potrzebuje fizycznego miejsca, żeby zapisać twój kod w Pythonie, tak aby pozostał dostępny długo po rozłączeniu twojej sesji. Z tego powodu musisz również podać parametr stage location. Wskazuje on na istniejący wewnętrzny stage w Snowflake'u. Snowpark zuploaduje i bezpiecznie przechowa skompilowane pliki Pythona bezpośrednio na tym stage'u. Po zakończeniu rejestracji, każdy z odpowiednimi uprawnieniami do bazy danych może wywołać twoją customową logikę w Pythonie prosto ze standardowego zapytania SQL. Podczas tworzenia dowolnego UDF-a, Snowpark zazwyczaj opiera się na pythonowych type hintach, aby zrozumieć, jakie typy danych funkcja akceptuje i zwraca. Jeśli twoja funkcja oczekuje stringa i zwraca stringa, dodajesz te standardowe type hinty do definicji w Pythonie, a Snowpark automatycznie mapuje je na odpowiednie typy danych Snowflake'a. Prawdziwą mocą skalarnego UDF-a jest nie tylko możliwość pisania w Pythonie, ale też możliwość wykonywania tego kodu w rozproszonej pamięci silnika bazy danych, co całkowicie eliminuje network latency związane z wyciąganiem danych do przetwarzania. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
12

Zarządzanie zależnościami dla UDFs

3m 49s

Dowiedz się, jak importować biblioteki firm trzecich i lokalne moduły do swoich Snowflake UDFs, używając kanału Anaconda i importów w ramach Session.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 12 z 17. Uruchamianie zewnętrznych pakietów Pythona w bazie danych kiedyś oznaczało dependency hell. Musiałeś budować skomplikowane kontenery Dockera tylko po to, żeby przepuścić array przez funkcję matematyczną. Teraz wystarczy do tego dokładnie jedna linijka kodu. W tym odcinku omówimy Dependency Management dla UDF-ów. Kiedy piszesz User-Defined Function, czyli UDF, twoja logika rzadko istnieje w próżni. Potrzebujesz bibliotek. W tradycyjnym setupie, przeniesienie twojego kodu w Pythonie tam, gdzie żyją dane, oznacza, że musisz też przenieść całe swoje środowisko. Martwisz się o pip installs, zależności kompilatora i utrzymanie serwera w stanie identycznym z twoją maszyną lokalną. Snowflake automatycznie unika tego koszmaru dzięki wbudowanej integracji z kanałem Anaconda. Kanał Anaconda w Snowflake hostuje tysiące gotowych, prekompilowanych pakietów Pythona, które mają gwarancję działania w execution environment Snowflake'a. Żeby z nich skorzystać, nie instalujesz niczego ręcznie. Po prostu deklarujesz, czego potrzebuje twoja funkcja. Kiedy definiujesz swojego UDF-a używając dekoratora w Pythonie, dodajesz parametr o nazwie packages. Przekazujesz do tego parametru listę stringów z nazwami bibliotek, których potrzebujesz. Weźmy konkretny scenariusz. Chcesz użyć modelu machine learningowego, żeby oceniać wiersze bezpośrednio w query w Snowflake'u. Twoja funkcja predykcyjna polega na scikit-learn i pandas. Tuż nad swoją funkcją w Pythonie dodajesz dekorator UDF i ustawiasz listę packages tak, żeby zawierała stringi scikit-learn i pandas. Nie budujesz kontenera i nie uruchamiasz package managera. Kiedy wywołujesz tego UDF-a, Snowflake prowizjonuje bezpieczne środowisko, zaciąga dokładnie te pakiety z kanału Anaconda i wykonuje twój kod. Jeśli potrzebujesz konkretnego wydania, możesz przypiąć wersję, dodając dwa znaki równości i numer wersji bezpośrednio w stringu, dokładnie tak samo jak w standardowym pliku requirements w Pythonie. To by było na tyle, jeśli chodzi o zewnętrzne biblioteki. Teraz druga część, czyli twój własny, customowy kod. Nie wszystko, co piszesz, nadaje się do Anacondy. Często masz helpery albo customowe reguły biznesowe napisane w osobnym pliku w Pythonie. Snowflake obsługuje ten first-party kod poprzez twoją aktywną sesję. Wywołujesz metodę o nazwie add import na obiekcie sesji. Przekazujesz ścieżkę swojego customowego pliku do add import. Może to być lokalny plik w Pythonie na twoim laptopie, plik, który już siedzi w stage'u w Snowflake'u, albo archiwum zip zawierające głębszy katalog modułów. Kiedy rejestrujesz swojego UDF-a, Snowflake bierze wskazane przez ciebie pliki i je uploaduje. W runtime, Snowflake wypakowuje te pliki i umieszcza je bezpośrednio w system path odizolowanego środowiska, w którym działa twój UDF. Wewnątrz kodu twojej głównej funkcji, po prostu używasz standardowych instrukcji import w Pythonie, żeby zaciągnąć swoje customowe moduły, dokładnie tak, jakby siedziały lokalnie w tym samym folderze. Możesz swobodnie łączyć te dwa podejścia. Deklarujesz swoje zewnętrzne requirements przez parametr packages, i wstrzykujesz swoje wewnętrzne moduły używając add import. Snowflake buduje execution context, bezpiecznie łącząc binarki z Anacondy z twoimi customowymi plikami ze stage'a, zanim przetworzony zostanie choćby jeden wiersz danych. Oto kluczowa sprawa. Obsługując zależności w ten sposób, Snowflake całkowicie decoupluje twój kod funkcjonalny od infrastruktury potrzebnej do jego uruchomienia, pozwalając ci zdefiniować bezpieczne, rozproszone execution environment przy użyciu wyłącznie listy nazw i ścieżek do plików. Dzięki za wysłuchanie, happy coding wszystkim!
13

Budowanie User-Defined Table Functions

3m 53s

Wyjdź poza wartości skalarne. Dowiedz się, jak budować User-Defined Table Functions (UDTFs), aby zwracać wiele wierszy i kolumn z pojedynczego wejścia.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 13 z 17. Co robisz, gdy twoja funkcja w Pythonie musi zwrócić całą tabelę wyników zamiast tylko jednej wartości? Standardowe User-Defined Functions są świetne, ale są ściśle ograniczone do zwracania pojedynczej wartości skalarnej na jeden wiersz wejściowy. Kiedy musisz rozbić pojedynczy input na wiele outputów, budujesz User-Defined Table Function, czyli UDTF. Różnica jest fundamentalna. Standardowa funkcja zwraca jedną wartość. UDTF zwraca relację. Oznacza to, że zwraca strukturę tabelaryczną, którą możesz odpytywać, filtrować lub joinować z innymi tabelami dokładnie tak, jakby to była fizyczna tabela w twojej bazie danych. Wyobraź sobie konkretny scenariusz. Masz tabelę z kolumną zawierającą mocno zagnieżdżone, niestandardowe logi aplikacji w formacie JSON. Każdy wiersz przechowuje jeden ogromny wpis logu, ale ten pojedynczy wpis może zawierać pięć, dziesięć lub pięćdziesiąt różnych zdarzeń systemowych ukrytych głęboko w JSON-ie. Musisz znormalizować te dane programatycznie. Chcesz przekazać jeden string JSON i otrzymać ustrukturyzowaną tabelę, w której każde pojedyncze zdarzenie jest wyciągnięte do osobnego wiersza. Aby zbudować UDTF w Snowpark Python, nie piszesz zwykłej, samodzielnej funkcji. Piszesz klasę w Pythonie. Ta klasa działa jako handler dla funkcji tabelarycznej i orkiestruje logikę za pomocą maksymalnie trzech konkretnych metod. Pierwsza to metoda inicjalizacyjna. Jest ona opcjonalna. Snowflake uruchamia ją raz na partycję przed przetworzeniem jakichkolwiek wierszy. Jeśli twój parser logów musi skompilować złożone wyrażenie regularne albo zainicjować niestandardowy słownik stanu, robisz to właśnie tutaj, dzięki czemu koszt setupu ponosisz tylko raz na batch danych. Druga to metoda process. Jest to jedyna obowiązkowa metoda w tej klasie. Snowflake wywołuje ją dla każdego pojedynczego wiersza wejściowego. W naszym scenariuszu z logami, metoda process odbiera string JSON, rozpakowuje tablicę zdarzeń i iteruje po nich w pętli. To tutaj dzieje się cała konwersja. Zamiast zwracać końcową wartość, metoda process zwraca krotki przez yield. Każda zwrócona w ten sposób krotka natychmiast staje się nowym wierszem w twojej tabeli wyjściowej. Jeśli jeden string JSON z logiem zawiera dwanaście zdarzeń, metoda process zwraca dwanaście oddzielnych krotek, a Snowflake zamienia je w dwanaście osobnych wierszy wyjściowych. Trzecia to metoda end partition. Ona również jest opcjonalna. Snowflake odpala ją po tym, jak wszystkie wiersze w bieżącej partycji przejdą przez metodę process. Zazwyczaj używasz jej, jeśli agregowałeś stan w całej partycji i musisz zwrócić przez yield końcowy wiersz podsumowujący, albo po prostu żeby wyczyścić pamięć i zasoby. Kiedy rejestrujesz tę klasę handlera w Snowpark, musisz jawnie zadeklarować swój schemat wyjściowy. Ponieważ UDTF zwraca tabelę, silnik wykonawczy bazy danych musi znać dokładne nazwy kolumn i typy danych krotek, które zwracasz przez yield, jeszcze zanim zapytanie w ogóle się uruchomi. Oto kluczowy wniosek. UDTF-y wypełniają lukę między złożoną logiką w Pythonie a operacjami na relacyjnych bazach danych. Pozwalają ci opakować chaotyczne, proceduralne odgnieżdżanie danych w czysty interfejs tabeli, który reszta twojej aplikacji może natywnie odpytywać. Dzięki za spędzenie ze mną tych kilku minut. Do usłyszenia następnym razem, trzymaj się.
14

Tworzenie Stored Procedures

3m 51s

Zautomatyzuj swoje potoki w całości wewnątrz Snowflake. Odkrywamy tworzenie Stored Procedures do wykonywania złożonej logiki biznesowej i przepływu sterowania.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 14 z 17. Przestań płacić za zewnętrzny serwer do orkiestracji tylko po to, by uruchamiać skrypty Pythona, które mówią Snowflake'owi, co ma robić. Pisanie Stored Procedures przenosi ten control flow bezpośrednio na platformę danych. Ludzie często mylą stored procedures z User-Defined Functions, czyli UDF-ami. UDF nie służy do orkiestracji. UDF-y zwracają wartości wewnątrz query i transformują dane wiersz po wierszu. Stored procedures działają zupełnie inaczej. Wykonują całe skrypty, uruchamiają wiele queries i obsługują proceduralny control flow. Używasz ich do orkiestracji zadań, a nie do obliczania wartości kolumn. Aby utworzyć stored procedure w Snowpark Python, piszesz standardową funkcję w Pythonie. Kluczowym wymaganiem jest pierwszy argument tej funkcji. Zawsze musi to być obiekt Snowpark Session. Ten obiekt Session to twój aktywny link do bazy danych. Kiedy twoja procedura działa, używa tej sesji do wykonywania SQL statements, budowania DataFrames oraz odczytu lub zapisu danych. Aby powiedzieć Snowflake'owi, że ta funkcja to stored procedure, umieszczasz dekorator sproc bezpośrednio nad definicją funkcji. Dekorator działa jako warstwa konfiguracji. Używasz go do określenia return type twojej procedury i wszelkich zewnętrznych pakietów Pythona, których twój kod potrzebuje do działania. Kiedy wykonujesz kod rejestracyjny, Snowpark bierze twoją funkcję w Pythonie, pakuje ją razem z jej dependencies i rejestruje w Snowflake'u. Od tego momentu logika żyje wewnątrz bazy danych i wykonuje się na compute Snowflake'a. Pomyśl o nocnym data pipeline. Twój proces musi utworzyć tabelę tymczasową, załadować do niej surowe dane, wykonać serię wieloetapowych transformacji i na koniec wyczyścić obiekty tymczasowe. Jeśli uruchomisz to z zewnętrznego serwera, twój kod w Pythonie wysyła komendę przez sieć, czeka aż Snowflake skończy, odbiera wynik i wysyła kolejną komendę. Pisząc dokładnie tę samą logikę w Pythonie jako stored procedure, cały skrypt wykonuje się wewnątrz Snowflake'a. Używa obiektu Session, aby natywnie przejść przez tworzenie tabel i transformacje DataFrames. Nie ma żadnego network latency między logiką orkiestracji a danymi, na których operuje. Chociaż stored procedure nie zwraca wartości dla każdego wiersza tak jak UDF, to wciąż zwraca pojedynczą wartość po zakończeniu skryptu. Definiujesz ten return type, kiedy konfigurujesz dekorator sproc. Często jest to prosty string potwierdzający sukces, integer reprezentujący całkowitą liczbę przetworzonych wierszy, a nawet tabelaryczny wynik pokazujący execution log. Masz wybór, jak zdeployować ten kod. Możesz zdefiniować i uruchomić anonimową procedurę dynamicznie w skrypcie Pythona, jeśli potrzebujesz jej tylko w jednej sesji. W przypadku zautomatyzowanych pipelines, rejestrujesz ją jako stały obiekt. Snowflake przechowuje definicję, aby każdy autoryzowany użytkownik, zewnętrzna aplikacja lub zaplanowane zadanie mogło ją później wywołać. Oto kluczowa informacja. Pisanie stored procedure w Snowpark Python oznacza, że traktujesz Snowflake'a jako application runtime, a nie tylko storage layer. Przenosisz mózg swojej orkiestracji tuż obok danych, którymi steruje. Jeśli podoba ci się nasz podcast i chcesz wesprzeć naszą pracę, możesz nas znaleźć, wyszukując DevStoriesEU na Patreon. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
15

Trenowanie modeli ML w Snowflake

3m 43s

Odkryj, jak bezpiecznie trenować ciężkie modele uczenia maszynowego na hurtowniach zoptymalizowanych pod kątem Snowpark, używając niestandardowych Python Stored Procedures.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 15 z 17. Przenoszenie terabajtów bezpiecznych danych na zewnętrzny serwer do machine learningu jest powolne, kosztowne i ryzykowne. Spędzasz godziny na przepychaniu danych przez sieć, a twój zespół security denerwuje się, gdzie one trafią. A co, gdyby to compute przyszedł do danych? To główna idea stojąca za trenowaniem modeli ML wewnątrz Snowflake. Wykorzystując Snowpark Python, możesz trenować single-node modele machine learningowe bezpośrednio w swoim data warehouse za pomocą stored procedures. Dane nigdy nie opuszczają granic Snowflake. To rozwiązuje problem data gravity. Zamiast wyciągać miliony wierszy do osobnej instancji w chmurze, odpalasz swój skrypt treningowy dokładnie tam, gdzie aktualnie żyją dane. Trenowanie modelu ML wymaga załadowania datasetu do pamięci. Standardowy virtual warehouse w Snowflake jest zoptymalizowany pod kątem równoległych zapytań SQL, a nie do trzymania ogromnych datasetów w systemowej pamięci RAM. Jeśli spróbujesz wytrenować złożony algorytm na standardowym warehouse, prawdopodobnie trafisz na błędy out-of-memory i proces zcrashuje. Aby sobie z tym poradzić, potrzebujesz innego profilu compute. Snowflake udostępnia Snowpark-optimized warehouses specjalnie do tego zadania. Te warehouses zapewniają do szesnastu razy więcej pamięci na node w porównaniu ze standardowymi instancjami. Przejdźmy przez konkretny scenariusz. Musisz wytrenować model random forest z scikit-learn na ogromnym datasecie klientów. Zaczynasz od napisania stored procedure w Pythonie. Rejestrując tę procedurę, określasz wymagane pakiety Pythona, takie jak scikit-learn, pandas i joblib. Snowflake automatycznie provisionuje te zależności za pomocą zintegrowanego kanału Anaconda. Przypisujesz również procedurę do uruchomienia na twoim Snowpark-optimized warehouse. Wewnątrz procedury używasz obiektu sesji Snowpark do zdefiniowania zapytania o dane treningowe. Następnie wywołujesz metodę, aby przekonwertować ten dataframe Snowparka na standardowy dataframe pandas. Ta akcja zaciąga wyniki zapytania bezpośrednio do pamięci fizycznej node'a warehouse'u. Ponieważ sprovisionowałeś zoptymalizowany compute, jest mnóstwo pamięci RAM, aby pomieścić cały dataset na raz. Następnie inicjalizujesz swój model random forest i wywołujesz metodę fit, przekazując dataframe pandas. Procesor warehouse'u obsługuje cykl trenowania dokładnie tak, jak na dedykowanym serwerze do machine learningu. Kiedy model skończy się trenować, masz wytrenowany algorytm siedzący w pamięci tymczasowej środowiska uruchomieniowego. Musisz go spersistować do przyszłych predykcji, zanim stored procedure zakończy działanie. I tutaj wkracza serializacja. Używasz biblioteki takiej jak joblib do spakowania modelu. Bierzesz wytrenowany obiekt modelu z pamięci i robisz dump do pliku, tworząc artefakt. Następnie instruujesz stored procedure, aby zapisała ten nowo utworzony plik bezpośrednio na wewnętrzny stage Snowflake'a. Stage działa jak bezpieczny folder storage'owy powiązany z twoim kontem Snowflake. Oto kluczowa kwestia. Twoja stored procedure działa jak bezpieczny kontener łączący twoje surowe tabele ze standardowymi bibliotekami machine learningowymi Pythona. Trzymając cały pipeline całkowicie wewnątrz Snowflake, zbijasz network latency do zera, omijasz wszystkie operacje data egress i utrzymujesz ścisłą kontrolę dostępu, a wszystko to pisząc dokładnie ten sam kod treningowy w Pythonie, który już znasz. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
16

Dynamiczny dostęp do plików z SnowflakeFile

3m 45s

Dowiedz się, jak dynamicznie przesyłać strumieniowo duże, nieustrukturyzowane pliki z internal stages bezpośrednio wewnątrz Twoich UDFs i Stored Procedures.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 16 z 17. Jak przetwarzać gigabajtowe, niestrukturyzowane pliki wewnątrz user-defined function, nie przekraczając limitów pamięci? Jeśli spróbujesz zmapować duże pliki jako static dependencies, system spróbuje pobrać wszystko z góry, a twój kod po prostu crashuje. Rozwiązaniem tego problemu jest Dynamic File Access za pomocą SnowflakeFile. Żeby zrozumieć, dlaczego to ma znaczenie, spójrz, jak normalnie działa file access w Snowparku. Zazwyczaj używasz parametru imports, żeby podpiąć plik do swojej funkcji. To statyczne podejście świetnie sprawdza się w przypadku małych plików konfiguracyjnych lub specjalistycznego modelu machine learning, ponieważ plik jest pobierany do compute warehouse przed rozpoczęciem wykonywania kodu. Ale to sypie się przy dużej skali. Jeśli twój pipeline musi przetwarzać setki ogromnych plików z logami serwera lub PDF-ów w wysokiej rozdzielczości przechowywanych na Snowflake stage, statyczne pobieranie ich wszystkich jest niesamowicie wolne i gwarantuje out-of-memory error. Tutaj do gry wchodzi klasa SnowflakeFile. Znajdująca się w module snowflake dot snowpark dot files, klasa ta pozwala twojej funkcji lub stored procedure otwierać pliki bezpośrednio ze stage'a w runtime. Nie bindujesz pliku podczas tworzenia funkcji. Zamiast tego, twoja funkcja przyjmuje lokalizację pliku jako standardowy argument typu string. Kiedy wywołujesz funkcję w swoim zapytaniu SQL lub operacji na dataframe, przekazujesz tę lokalizację. Wewnątrz kodu w Pythonie wywołujesz metodę open na klasie SnowflakeFile i przekazujesz jej string z lokalizacją pliku. Określasz również read mode, używając standardowych konwencji Pythona, takich jak r dla tekstu lub r b do czytania bajtów. Oto kluczowa sprawa. Wywołanie open nie ładuje pliku. Zwraca file-like object, który streamuje dane. Plik zostaje na stage'u, a ty zaciągasz dane przez network pipe. Zastosujmy to do scenariusza log processing. Masz tabelę w bazie danych, gdzie każdy wiersz zawiera scoped URL wskazujący na inny, duży log file na internal stage. Przekazujesz tę kolumnę z URL-em do swojej funkcji. Wewnątrz funkcji otwierasz stream i piszesz standardową pętlę, żeby czytać plik linijka po linijce. Kiedy twój kod ewaluuje każdą linijkę, żeby wyciągnąć kody błędów albo timestampy, Python usuwa poprzednie linijki z pamięci. Możesz parsować pięćdziesięciogigabajtowy log file, podczas gdy twoja funkcja trzyma w pamięci tylko jedną linijkę tekstu w danej milisekundzie. Dokładnie ten sam koncept działa dla plików binarnych. Jeśli wyciągasz tekst z dużych PDF-ów, otwierasz plik w binary mode i przekazujesz wynikowy stream bezpośrednio do biblioteki w Pythonie do parsowania PDF-ów. Biblioteka czyta byte stream sekwencyjnie, bez konieczności trzymania całego dokumentu w pamięci systemowej. SnowflakeFile automatycznie obsługuje również security boundary. Kiedy przekazujesz dynamicznie wygenerowany scoped URL do swojej funkcji, Snowflake przyznaje read access do tego konkretnego pliku tylko na czas trwania query, który wygasa natychmiast po jego zakończeniu. Streamowanie dynamically specified files utrzymuje twój memory footprint na płaskim poziomie niezależnie od rozmiaru pliku, pozwalając twojemu compute warehouse skupić się całkowicie na przetwarzaniu danych, zamiast tylko na próbach ich utrzymania w pamięci. To wszystko w tym odcinku. Dzięki za wysłuchanie i keep building!
17

Testowanie Snowpark Python

3m 45s

Upewnij się, że Twoje potoki danych są solidne. Omawiamy konfigurację PyTest, tworzenie fixtur Session oraz testowanie jednostkowe przekształceń DataFrames.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. Snowflake i Snowpark Python, odcinek 17 z 17. Nigdy nie zdeployowałbyś kodu backendowego bez unit testów, więc dlaczego data pipeline'y są często wrzucane na produkcję na żywioł? Snowpark to zmienia, sprawiając, że twoja logika danych staje się modułowa, co oznacza, że w końcu możesz ją testować jak normalny soft. Testowanie w Snowpark Python to krok, który wprowadza rygor software engineeringu do data engineeringu. Snowpark pozwala wyciągnąć logikę transformacji z monolitycznych skryptów i przenieść ją do samodzielnych funkcji w Pythonie. Ponieważ te funkcje przyjmują DataFrame na wejściu i zwracają DataFrame na wyjściu, możesz je testować przy użyciu standardowych frameworków w Pythonie. PyTest to najczęstszy wybór. Żeby uruchomić jakikolwiek kod w Snowparku, potrzebujesz aktywnej sesji. Zamiast zaszywać dane uwierzytelniające w każdym pojedynczym teście, definiujesz fixture sesji. Robisz to w dedykowanym pliku konfiguracyjnym o nazwie conftest.py, który PyTest automatycznie rozpoznaje. W tym pliku piszesz funkcję setup, która nawiązuje połączenie ze Snowflake, zwraca obiekt sesji i zamyka ją po zakończeniu testów. Dekorujesz tę funkcję jako fixture w PyTest. Teraz każdy test w twoim projekcie może zażądać aktywnej sesji, po prostu podając jej nazwę w argumentach funkcji testowej. Zastosujmy to do konkretnego scenariusza. Masz złożoną, customową transformację DataFrame, która odfiltrowuje nieaktywnych użytkowników, wylicza risk score i standaryzuje nazwy kolumn. Musisz zwalidować tę logikę przed zdeployowaniem pipeline'u na produkcję. Zaczynasz od napisania testu. Pierwszym krokiem w tym teście jest stworzenie wejściowego DataFrame'a, zawierającego kilka wierszy starannie dobranych, mockowych danych. Definiujesz dokładne nazwy kolumn i wartości wierszy potrzebne do wywołania konkretnych edge case'ów w twojej logice. Używasz swojego fixture'a sesji, żeby przekonwertować te surowe, mockowe dane na Snowpark DataFrame. Następnie przekazujesz ten mockowy, wejściowy DataFrame do swojej funkcji transformacji. Funkcja aplikuje twoją logikę biznesową i zwraca właściwy, wyjściowy DataFrame. Teraz musisz zweryfikować, czy logika zrobiła to, co do niej należało. Tworzysz w teście drugi mockowy DataFrame, tym razem reprezentujący dokładnie oczekiwany wynik. I to jest najważniejsza część. Musisz porównać otrzymany DataFrame z oczekiwanym DataFrame'em. Nie możesz jednak po prostu użyć standardowego sprawdzenia równości w Pythonie na samych obiektach DataFrame, ponieważ są one jedynie referencjami do query planów. Zamiast tego musisz porównać dane, które zawierają. Wywołujesz metodę collect zarówno na otrzymanym, jak i oczekiwanym DataFrame'ie, żeby zaciągnąć wyniki z powrotem do pamięci jako listy obiektów wierszy. Ponieważ rozproszone bazy danych nie gwarantują kolejności w result setach, chyba że jawnie się to wskaże, bezpośrednie porównanie dwóch list wierszy może nie przejść, nawet jeśli dane są poprawne. Żeby to naprawić, sortujesz obie listy wierszy przed zrobieniem asserta na ich równość. Jeśli posortowane, otrzymane dane pasują do posortowanych, oczekiwanych danych, twój test przechodzi. Przepuszczając małe, kontrolowane zbiory danych przez izolowane funkcje transformacji, wyłapujesz błędy logiczne lokalnie, zanim w ogóle dotkną tabeli na produkcji. To izoluje komponenty twojego pipeline'u i sprawia, że twój workflow w data engineeringu jest równie niezawodny, co tradycyjny software development. To już koniec naszej serii o Snowpark Python. Zachęcam cię do przejrzenia oficjalnej dokumentacji Snowflake'a, spróbowania napisania tych testów samemu, lub odwiedzenia devstories.eu, żeby zasugerować tematy do naszych przyszłych serii. Chciałbym poświęcić chwilę, żeby podziękować ci za słuchanie — to bardzo nam pomaga. Trzymaj się!