Integracja różnych źródeł informacji jest kluczowa dla efektywnego zarządzania i analizy danych. Jednym z narzędzi, które znacząco ułatwia ten proces, jest Matillion – platforma ETL/ELT zaprojektowana do pracy z chmurą.
Matillion to nowoczesne rozwiązanie umożliwiające łatwe przetwarzanie, transformację i ładowanie danych do hurtowni danych takich jak Snowflake, BigQuery czy Redshift. Dzięki intuicyjnemu interfejsowi i bogatemu zestawowi komponentów, Matillion pozwala na szybkie budowanie przepływów danych bez konieczności pisania dużej ilości kodu.
W tym artykule skupię się w szczególności na opisaniu procesu pozyskania danych poprzez API (Application Programming Interface) na przykładzie danych o zadaniach zaraportowanych w systemie Jira.
W tym przypadku wykorzystanie API jest przydatne do uzyskania aktualnych informacji o zadaniach, statusach, przypisanych osobach i innych kluczowych danych projektowych. Dość często API jest jedynym interfejsem pozyskania danych, gdyż bezpośredni dostęp do bazy danych systemu źródłowego nie zawsze leży w zasadach bezpieczeństwa, licencji i administracji w korporacji, a dostęp pośredni poprzez wyeksportowane pliki wiąże się z pewnymi opóźnieniami i innymi problemami.
Integracja z API
Matillion oferuje kilka komponentów do integracji z API:
- API Query Component – komponent zaprojektowany do pobierania danych z API opartych na JSON/XML. Umożliwia tworzenie profili API i mapowanie danych na strukturę tabelaryczną. Jest idealny do wykonywania zapytań i pobierania danych w strukturze tabelarycznej z możliwością filtrowania i sortowania.
- Python Script Component – pozwala na pisanie własnych skryptów w Pythonie, np. z użyciem biblioteki requests, co daje pełną kontrolę nad zapytaniami i odpowiedziami API. Do transformacji danych w formacie JSON do formatu tabelarycznego należy użyć innych dostępnych bibliotek.
- API Extract Component – kuzyn API Query komponent, jest zoptymalizowany do pobierania dużych ilości danych i ich ładowania do bazy danych, co jest bardziej efektywne w przypadku masowych operacji.
Różnice między API Query a Python z biblioteką requests:
| Cecha | API Query | Python Script (requests) |
| Łatwość użycia | Wysoka – interfejs graficzny | Średnia – wymaga znajomości Pythona |
| Elastyczność | Ograniczona do struktury JSON/XML | Bardzo wysoka – pełna kontrola |
| Obsługa błędów | Podstawowa | Możliwość zaawansowanej obsługi błędów |
| Integracja z Matillion | Bezpośrednia | Wymaga ręcznego mapowania danych |
| Wydajność | Optymalna dla prostych zapytań | Lepsza dla niestandardowych API |
Ograniczenia API Query component w Matillion
API Query component w Matillion ma kilka ograniczeń, które warto wziąć pod uwagę:
- Struktura danych
- Profile API: API Query component wymaga zdefiniowania profilu API, który opisuje strukturę API i mapuje dane na tabele, wiersze i kolumny. Proces ten może być skomplikowany, szczególnie dla bardziej złożonych API.
- Wydajność
- Duże zbiory danych: Pobieranie dużych ilości danych może wpływać na wydajność. Optymalizacja zapytań (filtry) i użycie paginacji są kluczowe dla utrzymania efektywności.
- Złożoność zapytań: Bardziej skomplikowane zapytania mogą wymagać więcej czasu na przetworzenie, co może wpływać na czas odpowiedzi.
- Uwierzytelnianie
- Metody uwierzytelniania: API Query component obsługuje różne metody uwierzytelniania, takie jak klucze API, tokeny Bearer, OAuth i inne. Konfiguracja tych metod może być czasochłonna i wymagać dodatkowej uwagi.
- Bezpieczeństwo
- Przechowywanie kluczy: Klucze API i tokeny uwierzytelniające muszą być przechowywane w bezpieczny sposób, aby zapobiec nieautoryzowanemu dostępowi.
- Zmiany w strukturze tabel
- Potencjalne zmiany: Jeśli struktura docelowej tabeli ulegnie zmianie, tabela może zostać ponownie utworzona lub wyczyszczona. Ważne jest, aby nie modyfikować struktury tabeli ręcznie.
- Certyfikaty SSL
- API Query component może mieć problemy z certyfikatami SSL, szczególnie jeśli serwer API używa samopodpisanych lub nieweryfikowalnych certyfikatów. Konfiguracja akceptacji wszystkich certyfikatów może być konieczna.
Przykład: Pobieranie danych z Jira API przy użyciu API Query
Ważne: Dla celów artykułu kilka tematów zostało uproszczonych. Dla bezpieczenstwa i zgodności z polityką firmy skontaktuj sie z lokalnym dzialem IT.
Scenariusz: Sprawdź, jakie zadania Jira są zakomitowane do brancha QA. Następnie pobierz dla nich: numer (key), nazwę (summary), status oraz przypisaną osobę (assignee). Jeśli wszystkie zadania mają status „Done”, wykonaj operację Merge z QA do PROD, a następnie, wykorzystując numer oraz nazwę, uzupełnij „Release Notes”.
Krok 1: Token API
- Przejdź do Jira.
- My API tokens (API Token Authentication).
- New API token
- Read (jest wystarczający dla naszych celów),
- Expiration (zależy od security policy).
- Po kliknięciu „Create” skopiuj token w bezpieczne miejsce. Jest on dostępny w Jira do podglądu i skopiowania tylko raz.

Krok 2: Query Profile
- Przejdź do „Manage API Profiles” i utwórz nowy profil „API_Jira”.
- Następnie wybierz Configure Query Profile.
- Kliknij „New Endpoint” i nadaj nazwę jira_tickets_enpoint.
- Skonfiguruj:
- URI -> https://jira.domain.com/rest/api/2/issue/XYZ-321
- Method: GET
- Auth -> ustaw Bearer Token i wklej Jira API Token (z kroku 1.)
- Params -> puste (Content-Type: application/json jest niewymagany)
- Body -> puste
- Po kliknięciu „Send” w zakładce „Response” powinny być widoczne dane o tym zadaniu w formacie JSON. Jeśli nie, to sprawdź w zakładce Log, jaki jest kod błedu.
- Kliknij „Next”.
- Pozostaw „Repeating element” jako domyślny -> /
- W oknie „Select fields” wybierz pola:
- /json/key
- /json/fields/summary
- /json/fields/status/name
- /json/fields/assignee/displayName
- Paging -> disabled (w tym scenariuszu nie potrzebujemy, gdyż iterator załatwia sprawę).
- Po kliknięciu „Next” w panelu Data Preview powinien być widoczny 1 wiersz z wypełnionymi 4 kolumnami dla tego zadania.
- Kliknij „Finish”.
- W głównym oknie kliknij „Test”, następnie: jira_tickets_enpoint i podobnie jak na Data Preview powinna byc widoczna tabela z 1 wierszem.
- Kliknij „Advanced Mode”, aby zmodyfikować endpoint i dodać parametr URI.
- Najpierw wyczyść wartość URI:
<api:set attr=”uri” value=”” /> - Następnie dodaj parametr:
<api:set attr=”paramname#1″ value=”uri” />
<api:set attr=”paramvalue#1″ value=”[_connection.uri]” />
Chcemy, żeby URI było przekazywane przez zmienną, która będzie się aktualizować z każdym wierszem z tabeli (pobieranym iteratorem).
- Najpierw wyczyść wartość URI:
- Docelowo, chcemy mieć taką konfigurację dla naszego endpointa:
<api:script xmlns:api="http://apiscript.com/ns?v1" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<api:info title="jira_tickets_endpoint" desc="Generated schema file." xmlns:other="http://apiscript.com/ns?v1">
<attr name="key" xs:type="string" readonly="false" other:xPath="/json/key" />
<attr name="fields.summary" xs:type="string" readonly="false" other:xPath="/json/fields/summary" />
<attr name="fields.status.name" xs:type="string" readonly="false" other:xPath="/json/fields/status/name" />
<attr name="fields.assignee.displayName" xs:type="string" readonly="false" other:xPath="/json/fields/assignee/displayName" />
</api:info>
<api:set attr="DataModel" value="DOCUMENT" />
<api:set attr="uri" value="" />
<api:set attr="JSONPath" value="/" />
<api:set attr="paramname#1" value="uri" />
<api:set attr="paramvalue#1" value="[_connection.uri]" />
<api:script method="GET">
<api:set attr="method" value="GET"/>
<api:call op="jsonproviderGet">
<api:push/>
</api:call>
</api:script>
</api:script>
- Na koniec warto usunąć w oknie „Manage Connection Options” parametr z Bearer Token.
Krok 3: Orchestration Job
- Utwórz zmienną (Job Variable): jv_jira_task z domyślnymi ustawieniami Text, Shared, Public.
- Stwórz dwie tabele (w bazie danych):
- tabela wejściowa: [Jira_tickets_input]
- Kolumna JIRA_TASK typu varchar
- Dane są w postaci: https://jira.domain.com/rest/api/2/issue/XYZ-321
Poprawność URL można przetestować w przeglądarce internetowej. - Komendy insert SQL dla wielu wierszy można zbudować przy pomocy Excela albo Copilota i innych.
- tabela wyjściowa: [Jira_tickets_output]
- kolumny odpowiednie dla zestawu danych pobranego z API. W naszym uproszczonym przypadku (bez zmiany nazw kolumn) jako varchar:
- key
- fields.summary
- fields.status.name
- fields.assignee.displayName
- kolumny odpowiednie dla zestawu danych pobranego z API. W naszym uproszczonym przypadku (bez zmiany nazw kolumn) jako varchar:
- tabela wejściowa: [Jira_tickets_input]
- Skonfiguruj komponent [Truncate Table]:
- Target Table –> Jira_tickets_output (za kazdym uruchomieniem chcemy mieć pustą tabelę wyjściową)
- Skonfiguruj komponent [Table iterator]:
- Target Table –> Jira_tickets_input
- Column Mapping -> JIRA_TASK, jv_jira_task
- Skonfiguruj komponent [API Query]
- Authentication Method -> Bearer Token
- Bearer Token -> {API Token z kroku 1.}
- Bearer Token najlepiej przechowywać w „Password Manager”
- Connection Options -> wybierz parametr URI (będzie przekazywany do Query Profile), któremu przypisz wartość: ${jv_jira_task}
- Profile -> API_Jira
- Data Source -> jira_tickets_enpoint
- Data Selection ->wybierz wszystkie pola, czyli: key, fields.summary, fields.status.name, fields.assignee.displayName
- Target Table -> Jira_tickets
- Load Options -> On, Off, Off, On, Gzip (nie chcemy robić „recreate table” za każdym razem)
- Jeśli chcesz mieć dokładniejsze informacje o procesie połączenia z API i ewentualnych błędach, ustaw Auto Debug -> On oraz Debug Level -> 5. Po testach, można ustawic Auto Debug -> Off
Rezultat

Po uruchomieniu, w tabeli Jira_tickets_output powinny znaleźć się wszystkie wiersze z tabeli Jira_tickets_input z dodatkowymi informacjami takimi jak:
- numer,
- nazwa,
- status,
- przypisana osoba.
Dla porównania, skrypt Python z biblioteką request, również z wykorzystaniem komponentu [Table Iterator], mógłby wyglądać mniej więcej tak:
import requests
issue_key = jv_jira_task
base_url = "https://jira.domain.com"
endpoint = f"{base_url}/rest/api/2/issue/{issue_key}"
headers = {
"Authorization": "Bearer API_TOKEN",
"Accept": "application/json"
}
response = requests.get(endpoint, headers=headers)
if response.status_code == 200:
data = response.json()
issue_data = {
"key": data["key"],
"summary": data["fields"]["summary"],
"status": data["fields"]["status"]["name"],
"assignee": data["fields"]["assignee"]["displayName"] if data["fields"]["assignee"] else "Nieprzypisane"
}
print("Dane zadania Jira:")
for k, v in issue_data.items():
print(f"{k}: {v}")
else:
print(f"Błąd: {response.status_code} - {response.text}")

Podsumowanie
W artykule przedstawiłem, jak wykorzystać komponent API Query w Matillion do integracji z Jira API, pokazując krok po kroku, w jaki sposób pobrać dane o zadaniach – ich numer, nazwę, status oraz przypisaną osobę.
API Query okazał się narzędziem:
- łatwym w konfiguracji, dzięki graficznemu interfejsowi,
- skutecznym w pobieraniu danych opartych na JSON z API,
- z dobrze zintegrowanym przepływami ETL w Matillion.
Dzięki zastosowaniu profilu API i komponentu API Query możliwa jest szybka automatyzacja pobierania danych projektowych z Jira, bez konieczności pisania kodu. To rozwiązanie sprawdza się szczególnie dobrze w przypadku standardowych zapytań, gdzie liczy się prostota i szybkość wdrożenia.
Dla bardziej złożonych scenariuszy, np. dynamicznych zapytań, niestandardowej paginacji czy zaawansowanej obsługi błędów, warto rozważyć użycie komponentu Python Script z biblioteką requests.
Integracja Matillion z Jira to świetny przykład, jak połączyć świat zarządzania projektami z analizą danych, umożliwiając tworzenie raportów, dashboardów i automatycznych alertów w oparciu o dane z codziennej pracy zespołów.
Zostaw komentarz