čtvrtek 21. října 2010

ODI 11g a SAP ERP - Extrakt dat ze SAPu

Fakta:
  • Zákazník provozuje SAP ERP
  • Do datového skladu je potřeba čerpat data přímo ze SAPu ERP na logické úrovni
  • Využit ODI SAP ERP aplikační konektor a SAP JCO konfigurovaný v předchozím článku
  • Nainstalované ODI11g, master i workrepository, Standalone Agent
  • Protože jsme prováděli na vývoji SAPu, neotestovali jsme zatím zda funguje při sadě oprávnění definované v práva
  • ODI Studio na win32 (windows 7 64 bit), DB Server a Standalone Agent Linux 64
  • Pro přenos extraktů jsme zvolili cestu, kdy máme zprovozněný FTP server (vsftpd), kam bude SAP ukládat extrakty a odkud je my budeme číst (ftp server běží na stejném HW jako DB resp. ODI agent kvůli rychlosti)
  • Infrastruktura (firewall) umožňuje konektivitu ze SAP serveru na náš server (pozor, nezapomenout), stejně tak náš FTP server resp. server má vypnutý firewall resp. nastavené porty (google help) – pozor, když testujete na své lokální mašině, musíte mít povolené na svém firewallu (a nebo ho na dobu otestování vypnout jako já)
  • Verze SAP JCO : sapjco30P_6-win_32bit_10005324 a stejná verze JCO pro linux 64 server
  • Verze LKM pro SAP ERP: Version: 11.1.2.24, Compatability:ODI 11.1.2 and above
  • Ze SAPu bereme celé tabulky (full snapshotů, ale s případným ořezáním na účetní okruh - filtry fungují, join jsme nezkoušel)

Zdroje:

(1) Dokumentace ODI 11g
(2) Dokumentace SAP ABAP ERP
(3) Google – pro konfiguraci vsftpd

Upozornění:
Oproti předchozímu článku si zjistěte od admina SAPu ještě jednu zásadní věc a to kódování, které SAP používá. Tady mají SAP ERP s kódováním SAP CP 1401, což je ISO 8859-2 (budeme je potřebovat později).


Postup na straně ODI:
1. Předpokladem je provedená a otestovaná konfigurace prostředí popsaná v předchozím článku

2. V topologii, jsem u SAP_ABAP Data serveru nastavil ve flexfiledu s názvem SAP CharakterSet hodnotu předanou adminem, tj. ISO-8859-2, aby mi to správně kódovalo řetězce

3. Pomocí Reverse engineeringu jsem ze SAPu reverzoval metadata několika tabulek (BKPF) (platí dále upozornění, že tento revers můžete provést pouze pomocí lokálního agenta v ODI Studiu, a musíte mít na daném počítači instalované SAP JCO) – viz. předchozí díl. Toto proběhlo nad očekávání naprosto bez problému, dotáhl i popis sloupců.

4. Vytvořil a otevřel jsem model resp. diagram (na Oracle DB), kam jsem přetáhl tabulku BKPF, takže mi konvertoval datové typy.

A tady už se dostáváme k jádru pudla :o). Bohužel opět platí, že metadata jsou jedna věc a reálná data druhá věc. Konverze jako taková pracuje v pohodě, ale metadata SAPu nesouhlasí s tím, co je reálně v datech (při importu přetéká rozsahu sloupců atd). Tady máte dvě možnosti:

a) Věřit a pak postupně upravovat cílovou tabulku tak, aby se tam rozsahy vlezly (iterativní a hodně nasírající smyčka)

b) Změnit v cílové tabulce datový typy na obecný VARCHAR2(60) a při loadu ořezávat prázdné mezery

Já si pro tento test vybral první cestu, ale tak mě to naštvalo, že už chystám speciální RKM, který půjde druhou cestou i s dalšími featurami (až bude ve zveřejnitelné podobě, publikuji tento KM jako přílohu u tohoto článku).

Pozor!!! Připomínám, toto přetažení nezkopíruje PK a UK, ty musíte vytvořit ručně.

5. Vytvořil jsem Interface, kde je zdrojem SAP tabulka a cílem Oracle DB, nastavení:

a. Filtr na zdrojové tabulce BKPF.BUKRS = '5000' – identifikace účetního okruhu, pokud je v SAPu najednou vedeno více firem. Zpracování na straně zdroje.

POZOR!!! U podmínek je důležitá jedna věc a to, že musí být s mezerami, tj. BKPF.BUKRS='5000' (hodnoty se uzavírají do apostrofu, v jiné formě háže ABAP chybu)
b. LKM KM – LKM SAP ERP To Oracle (SQLLDR) (Pozn. upravený dle postupu v tomto článku), konfigurace defaultní pro LKM

c. IKM KM – IKM Oracle Incremental Update


6. Opravy resp. zásahy do LKM SAP ERP To Oracle (SQLLDR)

a. Default option: FIELD_ SEPARATOR zvolil jsem pipe | ale záleži na Vás

b. Default option: FTP_PASSIVE_MODE=true – jen zkontrolujte, důležité kvůli firewallu, protože Passive mode běží na stejném portu, aktive vytváří spojení na vyšších portech (což Vám neprojde bez úpravy firewall nastavení). Passive bohatě stačí.

c. Klíčový je FTP_TRANSFER_METHOD=NONE – a zde jsem našel poměrně zásadní chybu resp. rozpor mezi dokumentací KM a kódem KM. Podle dokumentace v KM je nutné tuto hodnotu (FTP_TRANSFER_METHOD=NONE ) nastavit, aby SAP uploadoval na server (vždy přes FTP) a ODI už nic nepřetahuje (podmínkou je FTP server na stejném železe jako běží ODI agent a je i dostupný sqlldr). Asi po dvou dnech pátrání jsem našel chybu. Když dáte NONE, tak se Vám v generovaném ABAP kódu přestanou generovat příkazy na ftp přenos (upload souboru ze SAPu na FTP server), takže Vám sice ABAP vytvoří soubor, ale u sebe na lokále a vy máte smůlu :o). Jinou hodnotu pro připravenou infrastrukturu není možné použít, jinak bych musel přes ODI regulerně znovu stahovat ten samý file a nebo stejně šahat do kódu KM). Takže jsem ponechal NONE (dle dokumentace) a změnil jeden řádek v KM:

Změna je v Details, order 190 – název Extrakt Data v Command on Target najděte tuto sekvenci příkazů a nahraďte ji za tu níže uvedenou (je tam přidán jeden příkaz bUseFTP = true; )
<% // Init code gen vars boolean bUseFTP = false; if (odiRef.getOption("FTP_TRANSFER_METHOD").equals("FTP") || odiRef.getOption("FTP_TRANSFER_METHOD").equals("SFTP") || odiRef.getOption("FTP_TRANSFER_METHOD").equals("SCP")) { bUseFTP = true; }; %>

Nahraďte za sekvenci
<% // Init code gen vars boolean bUseFTP = false; bUseFTP = true; if (odiRef.getOption("FTP_TRANSFER_METHOD").equals("FTP") || odiRef.getOption("FTP_TRANSFER_METHOD").equals("SFTP") || odiRef.getOption("FTP_TRANSFER_METHOD").equals("SCP")) { bUseFTP = true; }; %>

Uložte změnu a máte hotovo z pohledu SAPu…


d. A pak tu máme další změnu (optional) – nevím, zda je to tím, že to běží na unixu, ale když se generuje CTL file, tak mi to tam dělalo psí kusy s uvozovkami a apostrofy. Protože já to měl na Linuxu, musel jsem upravit ještě další kousek KM, ale můžete zkusit, zda Vám to předtím neprojde bez této změny. Jedná se o datové typy DATE a asi i další, já šel cestou nejmenšího odporu, tj. měnil jsem jen to co mi bránilo:

Sekvence 210 Generate Loader Script
Řádek 93, původní verze:
return " DATE " + (char)34 + "YYYYMMDD" + (char)34 + " NULLIF " + colName + " = " +(char)34 + "00000000" + (char)34;

nahraďte:
return " DATE 'YYYYMMDD' NULLIF " + colName + " = '00000000'";

Pro zvídavé, je to proto, že SAP nezná null hodnotu, místo ní používá samé nuly, datum vede vždy ve formátu YYYYMMDD, takže ekvivalentně 00000000
Uložte změny

7. Zkontrolujte u interface, zda se promítly změny v default parametrech LKM SAP ERP to Oracle (SQLLDR)

8. A můžete spouštět…pozor, pokud používáte Standalone Agenta, musíte v něm mít nainstalované SAP JCO adaptéry (viz předchozí článek)


9. Další špek související s kódovou stránkou – pokud použivate UTF-8 nebo jinou codepage, jejíž pojmenování je stejné na SAPu i v Oracle DB, tak nemusíte řešit. Protože ale my máme na SAPu ISO-8859-2, tak máme problém. KM totiž tuto kódovou stranku doplní do parametru CHARACTERSET v ctl file pro SQL*Loader, který ji takto nezná. Ekvivalent je EE8ISO8859P2.

a. Abych toto ad hoc ošetřil, přidal jsem další flexfield pro technologii SAP ABAP (Security, Objects – Data Server, editovat, založka FlexFields, přidat položku a vyplnit viz. obrázek


b. V kódu s order 150 – Get SAP Info je nutné rozšíření kódu následovně (načtení hodnoty TARGET_DB_CHARACTERSET do proměnné sDBCharacterset):
Originál:


Nový kód:


c. V kódu 200-Generate Loader Script pak úprava kódu (jeden řádek) viz níže:
Originál

Nový kód

11. Aby se změny projevili, doporučuji restart ODI Studia

12. A pak už jen znovu start Interface

Protože píšu tento postup ex post, tak doufám, že jsme na nic nezapomněl … a tím končí éra placení šílených pěněz implementátorovi SAPu za přípravu extraktů pro DWH :o))))


V poslední článku mě čeká přechod na inkrementální načítání dat, už mám připraveno, ale musím ještě otestovat, abych Vás nekrmil bludy.


Petr Šimbera (BI/DW Architekt - Freelancer)

Žádné komentáře: