Ugrás a fő tartalomra

JIRA adatok adattárházba töltése

 JIRA adatok adattárházba töltése



🔄 Teljes folyamat áttekintése

1. Forrás rendszer: JIRA REST API

  • Feladat: Lekérni a kívánt adatokat a JIRA rendszerből (pl. issues, projects, users, stb.)

  • Technika: REST API hívásokat végzel, autentikációval (OAuth2 vagy token alapú).

  • Kimenet: JSON struktúrájú adatok

2. Mentés: JSON állományok naponta

  • Feladat: A REST API válaszokat fájlba menteni

  • Technika: Python/Powershell/shell script mentse a JSON-t strukturált fájlba (pl. jira_issues_YYYYMMDD.json)

3. Adattárház STAGE betöltés (Oracle)

  • Feladat: A JSON állományt feldolgozni és Oracle STAGE táblákba betölteni

  • Technika: Külső tábla (External Table), SQL*Loader, vagy Python + cx_Oracle

4. Továbblépés DW-be

  • Feladat: A STAGE táblából minősített adat betöltése a cél DW-be (dimensionek, ténytábla)

  • Technika: PL/SQL eljárások, mapping szabályok, időbélyeg, változáskezelés (SCD)


🧱 Részletes lépések és tanácsok

1. JIRA REST API hívás

  • Autentikáció: token (Basic Auth – email + API token), pl.:

    ---bash
    curl -u email@domain.com:APITOKEN "https://yourcompany.atlassian.net/rest/api/2/search?jql=..."
  • Figyelj a paginációra (limit pl. 100 találat/hívás): startAt, maxResults

  • Vedd ki az alábbi entitásokat:

    • issues (ticketek)

    • projects

    • users

    • statuses, resolutions, custom fields

  • Mentés JSON-be:

    • Napi dátummal ellátott fájlok

    • Kódolj jól a utf-8-re

    • Például Pythonban:

      ---python
      import requests, json, datetime headers = {"Authorization": "Basic YOURTOKEN"} response = requests.get("https://your.atlassian.net/rest/api/2/search?jql=...", headers=headers) with open(f"jira_issues_{datetime.date.today()}.json", "w", encoding="utf-8") as f: json.dump(response.json(), f, ensure_ascii=False, indent=2)

2. Oracle STAGE betöltés – JSON kezelése

Opciók:

  • A. JSON fájl feldolgozása Pythonból → Oracle-be (pl. cx_Oracle)

    • Megnyitod a fájlt

    • Bejárod az elemeket (pl. issue-k)

    • INSERT vagy MERGE művelettel betöltöd

  • B. External Table JSON támogatással (Oracle 19c+)

    • Oracle képes JSON-t fájlból olvasni SQL lekérdezéssel (Oracle Directory kell!)

    • Példa:

      ---sql
      CREATE TABLE jira_stage_json
      ( json_data CLOB ) ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY jira_dir ACCESS PARAMETERS ( RECORDS DELIMITED BY newline FIELDS (json_data CHAR(1000000)) ) LOCATION ('jira_issues_20250511.json') );

3. Adatmodellezés – STAGE tábla

  • STAGE tábla mindig 1:1-ben tükrözze a JSON struktúrát

  • Javasolt mezők:

    • issue_id, key, summary, status, assignee, created, updated

    • raw_json mező (eredeti teljes JSON, archiválás céljából)

  • Naplózás: load_date, source_file, insert_ts

4. ETL DW-be: PL/SQL vagy ETL tool (ODI, Talend)

  • STAGE → DW mapping:

    • issues → ténytábla (pl. fact_jira_issues)

    • users, projects, statuses → dimenziótáblák

  • Incrementális betöltés:

    • Kulcs mező pl. issue_id, updated mező alapján változáskezelés

  • Slowly Changing Dimension (SCD) ha pl. státusz vagy projekt neve változik

  • Data Quality ellenőrzés: kötelező mezők, enum értékek validálása


🛡️ Mire figyelj különösen oda

TémaMire figyelj?
API limitekRate limit – túl sok lekérdezés tiltást okozhat
Custom FieldsVáltozhat a struktúra projektfüggően – kezeld dinamikusan
JSON nested mezőkTöbb szinten lehetnek, bontsd szét táblákra
Inkrementális letöltésupdated >= last_run_time használata a JQL-ben
Time zone kezelésJIRA UTC-ban tárol, DW-ben lehet lokális időzóna
Adathibák kezeléseHiányzó mezők, hibás karakterek logolása
Naprakész adatmodellVerzióváltáskor ellenőrizd az API struktúraváltozásokat
AdatnaplózásMelyik fájlból, mikor, ki futtatta az ETL-t



🧪 Tesztelés és élesítés

  1. Készíts próba API hívást és ments el néhány ticketet

  2. Töltsd be kézzel a JSON-t egy STAGE táblába

  3. Írj PL/SQL scriptet, ami a STAGE-ből a DW táblába tölt

  4. Naplózd minden ETL lépést: siker/hiba, rekordszám, forrás fájl

  5. Automatizáld (pl. CRON, Oracle Scheduler, Airflow)




📌 1. JIRA API hívás és JSON mentés (Python példa)

A cél, hogy napi mentéssel lekérjük az összes JIRA ticketet, és elmentsük .json fájlba.

🔑 Előfeltételek:

  • JIRA API token: generálható a JIRA profilodban

  • requests modul telepítve

📄 jira_download.py – lekérdezi és elmenti a ticketeket:

---python
import requests
import json import datetime import os # Beállítások JIRA_URL = "https://yourcompany.atlassian.net" API_TOKEN = "your_api_token" EMAIL = "you@company.com" OUTPUT_DIR = "data" os.makedirs(OUTPUT_DIR, exist_ok=True) # Autentikáció headers = { "Authorization": f"Basic {EMAIL}:{API_TOKEN}".encode("utf-8").decode("utf-8"), "Content-Type": "application/json" } # Lekérdezendő JQL jql = "project = ABC AND updated >= -1d" max_results = 100 start_at = 0 issues = [] # Paginációs ciklus / issues oldalakra lebontott ciklus while True: url = f"{JIRA_URL}/rest/api/2/search" params = { "jql": jql, "startAt": start_at, "maxResults": max_results, "fields": "*all" } response = requests.get(url, headers=headers, params=params) data = response.json() issues += data.get("issues", []) if start_at + max_results >= data["total"]: break start_at += max_results # JSON mentés today = datetime.date.today().strftime("%Y%m%d") filename = os.path.join(OUTPUT_DIR, f"jira_issues_{today}.json") with open(filename, "w", encoding="utf-8") as f: json.dump(issues, f, ensure_ascii=False, indent=2) print(f"Sikeresen mentve: {filename}")

📌 2. Oracle STAGE tábla létrehozása (strukturált tábla JSON-hoz)

A JSON struktúrából bontsuk ki a szükséges mezőket:

🧱 Példa tábla: stg_jira_issues

---sql
CREATE TABLE stg_jira_issues ( issue_id VARCHAR2(20), key VARCHAR2(20), summary VARCHAR2(4000), project_key VARCHAR2(20), issue_type VARCHAR2(50), status VARCHAR2(50), assignee VARCHAR2(100), created_date DATE, updated_date DATE, raw_json CLOB, load_date DATE DEFAULT SYSDATE );

📌 3. Python kód: JSON betöltése Oracle-be (cx_Oracle)

📄 jira_load_to_oracle.py:

---python
import json import cx_Oracle import os import datetime # Csatlakozás Oracle DB-hez conn = cx_Oracle.connect("user/password@host:port/service_name") cursor = conn.cursor() # Fájl beolvasása today = datetime.date.today().strftime("%Y%m%d") file_path = f"data/jira_issues_{today}.json" with open(file_path, "r", encoding="utf-8") as f: issues = json.load(f) # Betöltés ciklus for issue in issues: fields = issue["fields"] cursor.execute(""" INSERT INTO stg_jira_issues ( issue_id, key, summary, project_key, issue_type, status, assignee, created_date, updated_date, raw_json ) VALUES ( :1, :2, :3, :4, :5, :6, :7, :8, :9, :10 ) """, ( issue.get("id"), issue.get("key"), fields.get("summary"), fields.get("project", {}).get("key"), fields.get("issuetype", {}).get("name"), fields.get("status", {}).get("name"), fields.get("assignee", {}).get("displayName") if fields.get("assignee") else None, fields.get("created")[:10], # ISO date fields.get("updated")[:10], json.dumps(issue) )) conn.commit() cursor.close() conn.close() print("Sikeres betöltés az Oracle STAGE táblába.")

📌 4. Oracle DW betöltés STAGE-ből

🎯 Cél: dw_fact_jira_issues (tényleges adattárház tábla)

---sql
CREATE TABLE dw_fact_jira_issues ( issue_id VARCHAR2(20) PRIMARY KEY, key VARCHAR2(20), summary VARCHAR2(4000), project_key VARCHAR2(20), issue_type VARCHAR2(50), status VARCHAR2(50), assignee VARCHAR2(100), created_date DATE, updated_date DATE, first_seen_date DATE, last_seen_date DATE );

🧠 PL/SQL: Inkrementális betöltés

---sql
MERGE INTO dw_fact_jira_issues tgt USING ( SELECT * FROM stg_jira_issues ) src ON (tgt.issue_id = src.issue_id) WHEN MATCHED THEN UPDATE SET key = src.key, summary = src.summary, status = src.status, assignee = src.assignee, updated_date = src.updated_date, last_seen_date = SYSDATE WHEN NOT MATCHED THEN INSERT ( issue_id, key, summary, project_key, issue_type, status, assignee, created_date, updated_date, first_seen_date, last_seen_date ) VALUES ( src.issue_id, src.key, src.summary, src.project_key, src.issue_type, src.status, src.assignee, src.created_date, src.updated_date, SYSDATE, SYSDATE );

📌 5. Automatizálás, ütemezés

  • Futtatási sorrend:

    1. jira_download.py – letöltés JSON-ba

    2. jira_load_to_oracle.py – betöltés Oracle STAGE-be

    3. PL/SQL script – betöltés DW-be

  • Scheduler lehetőségek:

    • Linux: cron

    • Windows: Task Scheduler

    • Oracle: DBMS_SCHEDULER

    • Profi megoldás: Apache Airflow


📋 Összegzés

LépésEszközFeladat
1. API hívásPython + RESTAdatok lekérdezése JIRA-ból
2. JSON fájlPythonNaplózott mentés
3. STAGE betöltésPython + cx_OracleJSON feldolgozás és insert
4. DW betöltésPL/SQLInkrementális frissítés
5. AutomatizálásCron / SchedulerNapi futás biztosítása



📦 1. JIRA JSON struktúra elemzés (példa)

A JIRA REST API issues lekérdezés válaszának egy jellemző részlete:

---json
{ "id": "10001", "key": "ABC-123", "fields": { "summary": "Login page not loading", "status": { "name": "To Do" }, "issuetype": { "name": "Bug" }, "project": { "key": "ABC" }, "assignee": { "displayName": "John Doe" }, "created": "2024-09-01T10:00:00.000+0000", "updated": "2024-09-02T12:30:00.000+0000" } }

👆 Fontos és gyakori JIRA mezők:

  • fields.summary, fields.status.name, fields.assignee.displayName

  • fields.customfield_10021 – ez projektfüggő egyedi mező lehet


🧰 2. Oracle JSON_TABLE használata

Ha Oracle 19c+ környezeted van, akkor közvetlenül JSON fájlból vagy CLOB mezőből lekérdezhetsz adatot SQL-ben.

📁 2.1. Külső fájl (External Table + JSON_TABLE)

A. Külső tábla JSON olvasáshoz:

---sql
CREATE OR REPLACE DIRECTORY jira_dir AS '/data/jira/'; GRANT READ, WRITE ON DIRECTORY jira_dir TO YOUR_USER; CREATE TABLE ext_jira_json ( json_text CLOB ) ORGANIZATION EXTERNAL ( TYPE ORACLE_LOADER DEFAULT DIRECTORY jira_dir ACCESS PARAMETERS ( RECORDS DELIMITED BY NEWLINE FIELDS (json_text CHAR(1000000)) ) LOCATION ('jira_issues_20250511.json') ) REJECT LIMIT UNLIMITED;

B. JSON_TABLE SQL:

---sql
SELECT * FROM ext_jira_json e, JSON_TABLE(e.json_text, '$' COLUMNS ( issue_id VARCHAR2(20) PATH '$.id', issue_key VARCHAR2(20) PATH '$.key', summary VARCHAR2(4000) PATH '$.fields.summary', status VARCHAR2(100) PATH '$.fields.status.name', assignee VARCHAR2(100) PATH '$.fields.assignee.displayName', created_dt DATE PATH '$.fields.created' FORMAT JSON DATE 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM', updated_dt DATE PATH '$.fields.updated' FORMAT JSON DATE 'YYYY-MM-DD"T"HH24:MI:SS.FF3TZH:TZM' ) ) jt;

📌 Ha több JSON objektum van egy fájlban (listaként), akkor NESTED PATH '$[*]' opciót kell használni a JSON_TABLE-ban!


🧪 3. PL/SQL eljárás naplózással

Cél: STAGE táblából DW-be betöltés + naplózva a beolvasott/hibás rekordok száma.

📄 pkg_jira_etl.p_load_jira_issues

---sql
CREATE OR REPLACE PACKAGE pkg_jira_etl AS PROCEDURE p_load_jira_issues; END pkg_jira_etl; / CREATE OR REPLACE PACKAGE BODY pkg_jira_etl AS PROCEDURE p_load_jira_issues IS v_inserted INTEGER := 0; v_updated INTEGER := 0; BEGIN MERGE INTO dw_fact_jira_issues d USING ( SELECT * FROM stg_jira_issues ) s ON (d.issue_id = s.issue_id) WHEN MATCHED THEN UPDATE SET d.status = s.status, d.updated_date = s.updated_date, d.last_seen_date = SYSDATE WHERE d.updated_date < s.updated_date WHEN NOT MATCHED THEN INSERT ( issue_id, key, summary, project_key, issue_type, status, assignee, created_date, updated_date, first_seen_date, last_seen_date ) VALUES ( s.issue_id, s.key, s.summary, s.project_key, s.issue_type, s.status, s.assignee, s.created_date, s.updated_date, SYSDATE, SYSDATE ); v_inserted := SQL%ROWCOUNT; INSERT INTO etl_log (job_name, status, records_inserted, run_date) VALUES ('JIRA_LOAD', 'SUCCESS', v_inserted, SYSDATE); COMMIT; EXCEPTION WHEN OTHERS THEN INSERT INTO etl_log (job_name, status, error_message, run_date) VALUES ('JIRA_LOAD', 'ERROR', SQLERRM, SYSDATE); ROLLBACK; RAISE; END; END pkg_jira_etl; /

📄 Log tábla:

---sql
CREATE TABLE etl_log ( id NUMBER GENERATED BY DEFAULT AS IDENTITY, job_name VARCHAR2(100), status VARCHAR2(20), records_inserted NUMBER, error_message VARCHAR2(4000), run_date DATE DEFAULT SYSDATE );

🔁 4. Automatikus futtatás Oracle-ben (DBMS_SCHEDULER)

🕒 Napi egyszeri futtatás PL/SQL eljárásra:

---sql
BEGIN
DBMS_SCHEDULER.create_job ( job_name => 'JIRA_DAILY_LOAD', job_type => 'STORED_PROCEDURE', job_action => 'pkg_jira_etl.p_load_jira_issues', start_date => SYSTIMESTAMP, repeat_interval => 'FREQ=DAILY;BYHOUR=7;BYMINUTE=0', enabled => TRUE, comments => 'Napi JIRA betöltés stage-ből DW-be.' ); END;

🎁 EXTRA: Egyedi mezők (customfield_*) kezelése

JIRA-ban gyakran használnak "custom field"-eket:

---json
"customfield_10021": "Customer priority"

👉 Célszerű ezeket egy külön táblába tenni:

---sql
CREATE TABLE stg_jira_customfields ( issue_id VARCHAR2(20), field_key VARCHAR2(100), field_value VARCHAR2(4000) );

Python feldolgozásnál:

---python
custom_fields = ["customfield_10021", "customfield_10045"] for field in custom_fields: value = fields.get(field) if value: cursor.execute(""" INSERT INTO stg_jira_customfields (issue_id, field_key, field_value) VALUES (:1, :2, :3) """, (issue["id"], field, str(value)))

✅ Összefoglalás

ModulTechnikaCél
JIRA API hívásPython, REST, JSONLetöltés
JSON parsingPython vagy JSON_TABLE (SQL)Betöltés
STAGE → DWPL/SQL MERGE + naplózásInkrementális frissítés
AutomatizálásDBMS_SCHEDULERNapi ütemezés
Egyedi mezőkcustomfield_* külön táblábaRugalmas tárolás









Megjegyzések