Projekt NBP w Fabric migracja do Databricks

  • Projekt NBP w Fabric migracja do Databricks

    Posted by Klaudia Kuszczak on 2026-08-09 at 09:21

    Cześć! Niedawno obroniłam pracę inżynierską „Projekt i implementacja systemu przetwarzania danych opartego o architekturę Lakehouse w Microsoft Fabric” i chcę podzielić się z wami projektem, który był jej największym elementem. Przy okazji dziękuję Markowi Czumie za solidną dawkę wiedzy o Sparku. Przydała się i od strony teorii i praktyki.

    https://github.com/klaudia-q/nbp-lakehouse-fabric

    W wielu projektach technologia zmienia się z różnych powodów. U mnie prozaicznie: wygaśnie dostęp do konta uczelnianego, a razem z nim do Fabrica. Uznałam to za dobrą okazję, żeby spróbować sił w migracji i przenieść projekt na Databricks, równolegle ucząc się z kursu Krzysztofa Nojmana.

    Im dłużej patrzę na własny kod, tym wyraźniej widzę, że parę rzeczy działa u mnie wyłącznie dlatego, że przy każdym uruchomieniu nadpisuję wszystko overwrite. Jak wejdzie MERGE, to się posypie.

    Najbardziej nie daje mi spokoju klucz surogatowy w wymiarze walut. Nadaję go row_number()em po kodzie waluty, od nowa przy każdym przebiegu. Teraz jest spójnie, bo fakty przeliczam w tym samym locie. Ale jak przejdę na przyrostowe i dojdzie nowa waluta gdzieś w środku alfabetu, numeracja się przesunie i fakty zapisane wcześniej zaczną wskazywać nie na to, co trzeba. Widzę trzy wyjścia i przy każdym mam wątpliwość. Mogę zrobić MERGE na wymiarze, żeby klucz dostawały tylko nowe kody, a stare zostawały nietknięte poprawnie, ale wprowadza stan, który trzeba pilnować. Mogę liczyć klucz deterministycznie, sha2(currency_code, 256) problem znika bez żadnego stanu, tylko dostaję nieczytelny string zamiast małego inta w tabeli faktów. Albo mogę w ogóle odpuścić surogat i zostawić sam currency_code: wymiar ma kilkadziesiąt wierszy, żadnej historii tam nie wersjonuję, a kod ISO jest stabilny.
    Ciągnie mnie do trzeciego, bo najprostsze, ale mam z tyłu głowy, że gdybym kiedyś chciała SCD2, sama sobie zamykam drogę. Robicie tak u siebie przy małych wymiarach, czy to jednak grzech?
    Druga rzecz, na której straciłam najwięcej czasu przy pisaniu: Bronze zapisywał przez .save(„Tables/…”), a Silver czytał przez nazwę tabeli. Pliki leżały gdzie trzeba, tylko Spark ich nie widział w katalogu. CREATE TABLE … LOCATION ze ścieżką względną nie pomogło, dopiero pełna abfss://. Zrzuty z całego grzebania wrzuciłam do repo, bo szkoda było wyrzucać. W Databricks pod Unity Catalog to pewnie w ogóle nie wystąpi, ale jestem ciekawa, czy ktoś świadomie trzyma zapis po ścieżce zamiast saveAsTable i ma ku temu powód, którego nie widzę.

    No i trzecia, bardziej modelowa. Łączę A z C full outer joinem, bo teoretycznie daty mogą się rozjechać. W praktyce na moich danych nie trafiłam na ani jeden wiersz bez pary, więc to jest inner udający coś więcej. Tu też mam dwie drogi: zostawić full outer i dorzucić coalesce() na nazwę waluty, albo zejść do innera i wywalać przypadki bez pary do logu jako anomalię. Druga wydaje mi się uczciwsza wobec danych, ale zakłada, że rozjazd między A i C to błąd, a nie dopuszczalny stan, czego szczerze mówiąc nie sprawdziłam w dokumentacji NBP.

    Jak ktoś przechodził już drogę Fabric -> Databricks, to chętnie posłucham, co sprawiło wam problem?

    Marek Czuma replied 1 day, 23 hours temu 3 Members · 2 Replies
  • 2 Replies
  • Przemysław Lelewski

    Member
    2026-08-09 at 15:33
    668 Exp

    Cześć

    a propos pierwszego problemu z „surrogate key” : mam sporo do czynienia na obecnym projekcie, ale składa się na nie kilka kolumn i dla nich nadawany jest klucz (integer). Z tego co widzę u Ciebie jest 1:1 czyli waluta:klucz. To jaki jest cel tworzenia takiego klucza i nie pozostawianie/wstawianie po prostu kodu waluty? (sorki, jeśli coś pomieszałem – jeśli chodzi o Sparka to jestem dopiero po kursie Marka i zwyczajnie nie zaczaiłem zbytnio kodu).

  • Marek Czuma

    Organizer
    2026-08-10 at 10:20
    5260 Exp

    Przede wszystkim – gratulacje obronionej inżynierki! I dobry pomysł z migracją projektu na DBX;-).

    Jeśli chodzi o klucz – to jaki jest cel nadawania czegoś jeszcze poza walutą? Jeśli masz kolumnę unikatową, to po prostu to może być jej kluczem:-). Dodam jeszcze, że bardzo dużo zależy tutaj od decyzji biznesowej oraz logiki systemu, bo musisz sobie odpowiedzieć na pytanie: „czy w dalszej części systemu zależy mi na tym, żeby wiedzieć, które wiersze są nowe?”. Jeśli tak, to można robić to przyrostowo poprzez merge. W Databricks możesz też wykorzystać mechanizm CDF. Jeśli nie – to tabelę która ma kilkadziesiąt wierszy WARTO (moim zdaniem) nadpisywać, bo kod jest znacznie prostszy.

    Na drugi problem nie jestem w stanie odpowiedzieć niestety, bo nie znam fabric :(. W Databricks do danych z ADLSa masz dostęp poprzez Volume i to Volume podpinasz do ADLS, więc sam kod pozostaje niezmienny – i pobierasz parquety normalnie, a jak kiedyś zmienisz środowisko to Volume po prostu zmienia źródło, kod się nie zmienia.

    Trzeci problem zależy od decyzji i logiki biznesowej. Tak jak napisałaś – zależy co jest błędem. Jeśli coś może być błędem, to CHCESZ O TYM WIEDZIEĆ – i warto zrobić tak jak napisałaś, wywalać do tabeli błędów, a sam job dalej leci z tematem.

Zaloguj się aby odpowiedzieć