fbpx
Big DataData SciencePoradniki

Czym jest profilowanie danych w pracy inżyniera danych?

Kiedy słyszymy ETL lub ELT pierwsze co przychodzi nam na myśl to transformacje, źródła oraz miejsce zapisu. Zastanawiamy się nad agregacją, odpowiednimi relacjami oraz jak ma wyglądać tabela końcowa. Natomiast jest wiele elementów na które również należy zwrócić uwagę, aby uniknąć błędów lub dodatkowej pracy w przyszłości.

Pierwszym takim elementem jest profilowanie danych (ang. Data Profiling). Jest to proces, w którym analizujemy nasze źródła oraz docelową strukturę danych, aby lepiej zrozumieć ich składnię oraz różnice pomiędzy nimi. Krótko mówiąc – sprawdź, co aktualnie masz, zanim przejdziesz do tworzenia „pipeline”. Dlaczego jest to aż tak ważne? W pracy inżyniera danych często pracujemy z wieloma źródłami, korzystamy z różnych narzędzi transformacji, a docelowe miejsce zapisu nie musi być zawsze tym samym systemem lub formatem plików. Załóżmy scenariusz, gdzie potrzebujemy zebrać informacje o zamówieniach z dwóch systemów źródłowych, zunifikować, a następnie zapisać do hurtowni danych.

Przykładowy proces ETL: źródła danych Oracle i SAP, silnik transformacji PySpark, hurtownia danych PostgreSQL
Rysunek 1 Przykładowy proces ETL i technologie

Nie wydaje się to trudne, prawda? Dwa źródła danych, oba korzystają z formatu tabeli. Zajrzymy teraz do przykładowych struktur danych w obu źródłach.

KolumnaTyp danych (Oracle)Przykład 1Przykład 2Przykład 3
ORDER_IDNUMBER(10)500001500002500003
CUSTOMER_IDNUMBER(10)100110021001
ORDER_DATEDATE10.02.202411.02.202412.02.2024
STATUSVARCHAR2(20)NEWSHIPPEDCANCELLED
PRODUCT_CODEVARCHAR2(30)PRD-2231PRD-8842PRD-1190
QUANTITYNUMBER(6)412
UNIT_PRICENUMBER(12,2)129.99899.0045.50
TOTAL_AMOUNTNUMBER(14,2)519.96899.0091.00
CURRENCYCHAR(3)PLNPLNEUR
CREATED_ATTIMESTAMP10.02.2024 08:1411.02.2024 13:4012.02.2024 16:05
Tabela 1 Tabela zamówień (Oracle)
KolumnaTyp danych (SAP)Przykład 1Przykład 2Przykład 3
VBELN (nr dokumentu sprzedaży)CHAR(10)600001600002600003
KUNNR (nr klienta)CHAR(10)100045100078100045
ERDAT (data utworzenia)DATS(8)202402102024021120240212
AUART (typ zamówienia)CHAR(4)ORORRE
VKORG (organizacja sprzedaży)CHAR(4)100010002000
NETWR (wartość netto)CURR(15,2)519.96899.0091.00
WAERK (waluta)CUKY(5)PLNPLNEUR
AUGRU (powód zamówienia)CHAR(3)(puste)14
LOEVM (oznaczenie do usunięcia)CHAR(1)(puste)(puste)X
Tabela 2 Tabela zamówień (SAP)

Pierwszy „problem” został już rozwiązany. Dodałem w nawiasach obok nazw kolumn w SAP ich znaczenie. Bez tego ciężko się domyśleć jakie informacje dostarczają nam tabele. Drugim problemem jest kolumna „Typ danych”. Każda technologia/silnik/narzędzie/itd. posiada często swój własny zestaw typów danych oraz mechanizmy do obsługi NULL. W bazach danych Oracle mamy dla łańcuchów znakowych typ VARCHAR2, SAP korzysta z CHAR, PySpark ma standardowy STRING, a nasza hurtownia danych, PostgreSQL zapisuje łańcuchy znakowe pod VARCHAR. Kolejnym przykładem jest data – Oracle ma DATE, w SAP widzimy DATS, który oznacza łańcuch znakowy w formacie YYYYMMDD, PySpark zapisze to z wykorzystaniem modułów datetime albo pendulum, a PostgreSQL będzie tutaj miał podobnie jak Oracle, czyli DATE. Wspomniałem o NULL i tutaj też jest ciekawie – Oracle, PostgreSQL korzystają z frazy NULL, PySpark ma swój typ None, ale w SAP NULL już nie istnieje – jest on mapowany zależnie od typu danych. Dla CHAR będzie to brak znaków, czyli pusty łańcuch znakowy, ale DATS wykorzysta zapis „00000000”. Podobnie z prawda/fałsz. W językach programowania jest dostępny typ bool/boolean, ale w bazach danych najczęściej prezentowane to jest za pomocą łańcucha znakowego Y/Yes/N/No albo liczbą całkowitą 0/1.

Drugim problemem jest mapowanie danych. Poza dopasowaniem kolumn musimy również (jeżeli jest to oczywiście możliwe) dopasować wartości. Ten problem nie występuje pomiędzy CURRENCY (Oracle), a WAERK (SAP) – po prostu przepisujemy informacje do wspólnej tabeli. Ale co mamy zrobić z informacją o dacie zamówienia? W Oracle mamy dwie informacje: ORDER_DATE oraz CREATED_AT. SAP posiada tylko jedną kolumnę: ERDAT. Tutaj Data Engineer musi współpracować z analitykami oraz biznesem, aby ustalić warunki mapowania danych oraz ich łączenia. Biznes może ustalić, że kolumna ORDER_DATE jest równa ERDAT, ale chce również informacje CREATED_AT w hurtowni danych. W takiej sytuacji najczęściej będziemy ustawiać NULL.

Ostatnim krokiem, który Data Engineer powinien wykonać jest dodanie kolumn technicznych. Są to dodatkowe kolumny, które dostarczają metadanych oraz pozwalają optymalizować kolejne procesy. Przykładowo:

  • Dodanie kolumn z informacjami skąd pobrano rekord oraz kiedy go zaktualizowano. Dzięki temu możemy zweryfikować, czy załadowaliśmy wszystkie dane z wybranego źródła.
  • Kolumna techniczna o nazwie „source_date”, która jest konkatenacją wartości z kolumny SourceSystem oraz ProcessDate. Dzięki temu możemy utworzyć partycjonowanie na jednej kolumnie, a następnie korzystać z tej kolumny podczas odczytywania danych dla kolejnych procesów.

Tak będzie prezentował się nasz szablon przepływu danych:

Proces ETL krok po kroku: ekstrakcja surowych danych z Oracle i SAP, czyszczenie NULL i trim pól CHAR, rzutowanie typów, ujednolicenie kluczy, kolumny techniczne, ładowanie do PostgreSQL
Rysunek 2 Kompletny opis procesu ETL

Na koniec ogólne zasady przy projektowaniu transformacji, niezależnie od silnika:

  • Nigdy nie mapuj wprost 1:1 typu źródłowego na docelowy — zawsze przechodź przez jawne rzutowanie (np. funkcja cast w PySpark), żeby uniknąć cichej utraty precyzji lub formatu.
  • Klucze biznesowe (ID, numery dokumentów) traktuj jako łańcuchy znakowe aż do momentu, gdy masz pewność co do formatu.
  • Kwoty i wartości pieniężne zawsze typy danych z jawną precyzją np. Decimal, Numeric — różnice w zaokrągleniach między systemami są częstym źródłem błędów w hurtowniach danych.
  • Wartości puste/domyślne różnią się między systemami — w naszym przykładzie Oracle używa NULL, SAP często pustego stringa lub „00000000” dla dat — normalizacja do NULL powinna nastąpić w warstwie transformacji przed zapisem do miejsca docelowego.
  • Kodowanie znaków — systemy mogą korzystać z różnych systemów kodowania. SAP bywa w kodowaniu specyficznym dla systemu (np. z uwzględnieniem znaków narodowych w polach CHAR) — warto zweryfikować UTF-8 przy ekstrakcji.
  • Nie używamy pustych znaków jako uzupełnienie – jeżeli zależy nam na stałej długości tekstu np. numer EAN to nigdy nie uzupełniamy go białymi znakami np. „011” zamiast „ 11”. Niektóre narzędzia potrafią ignorować białe znaki na początku i na końcu tekstu!
Piotr Chudzik

Piotr Chudzik [in]

Z IT jest związany już prawie 10 lat. Pracował w różnych sektorach związanych z danymi: od administratora baz danych, poprzez DataOps, a skończywszy na Data Engineer. Zajmuje się również planowaniem i zarządzaniem zespołów (aktualnie pracuje jako Technical Lead w firmie Kantar). Autor wideo kursów i książek o tematyce technicznej. Jak ma trochę wolnego czasu to spędza go na czytaniu książek fantasy lub graniu w gry komputerowe.

Back to top button