# AGGREGATED_ALLOTMENT External Tables - Rozwiązanie problemów ## 🔍 Diagnoza problemów ### Problem który napotkałeś: ```sql SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS; -- ORA-29913: error while processing ODCIEXTTABLEOPEN routine -- ORA-20401: Authorization failed ``` ### Przyczyny problemów: #### 1. **Brak uprawnień do external tables** - External tables zostały utworzone w schemacie **ODS** - Próbujesz dostępu z schematu **CT_MRDS** - Brak uprawnień SELECT na ODS.TOP_AGGREGATED_ALLOTMENT_* #### 2. **Niepoprawna konfiguracja ARCHIVE table** - **Użyty prefix:** `ARCHIVE/TOP/AGGREGATED_ALLOTMENT` - **Faktyczne pliki:** `TOP/AGGREGATED_ALLOTMENT/YEAR=2025/MONTH=08/*.parquet` - **Problem:** PARQUET files z Hive partitioning wymagają specjalnej konfiguracji #### 3. **Weryfikacja plików** ✅ ```bash # ODS bucket - pliki CSV istnieją oci os object list --bucket-name data --prefix "ODS/TOP/AGGREGATED_ALLOTMENT/" # ✅ 14 plików CSV # ARCHIVE bucket - pliki PARQUET z partycjonowaniem Hive oci os object list --bucket-name history --prefix "ARCHIVE/TOP/AGGREGATED_ALLOTMENT/" # ❌ Brak plików w tej lokalizacji oci os object list --bucket-name history --prefix "TOP/AGGREGATED_ALLOTMENT/" # ✅ 8 plików PARQUET w strukturze YEAR=2025/MONTH=08/ ``` ## 🔧 Rozwiązania ### Rozwiązanie 1: Nadanie uprawnień ```sql -- Jako ODS user lub ADMIN GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO CT_MRDS; GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_INBOX TO CT_MRDS; GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE TO CT_MRDS; -- Test z CT_MRDS SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS; ``` ### Rozwiązanie 2: Poprawa konfiguracji ARCHIVE table ```sql -- Jako ODS user DROP TABLE TOP_AGGREGATED_ALLOTMENT_ARCHIVE; -- Poprawne utworzenie z właściwym prefixem BEGIN FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE( pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE', pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT', pPrefix => 'TOP/AGGREGATED_ALLOTMENT', -- Bez "ARCHIVE/" prefix pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri ); END; / ``` ### Rozwiązanie 3: Alternatywne podejście - tworzenie w CT_MRDS ```sql -- Jako CT_MRDS user - utwórz external tables w swoim schemacie BEGIN CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE( pTableName => 'TOP_AGGREGATED_ALLOTMENT_ODS_CT', pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT', pPrefix => 'ODS/TOP/AGGREGATED_ALLOTMENT', pBucketUri => CT_MRDS.ENV_MANAGER.gvDataBucketUri ); END; / BEGIN CT_MRDS.FILE_MANAGER.CREATE_EXTERNAL_TABLE( pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE_CT', pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT', pPrefix => 'TOP/AGGREGATED_ALLOTMENT', pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri ); END; / ``` ## 🧪 Testowanie rozwiązań ### Test 1: Weryfikacja external locations ```sql SELECT table_name, location FROM all_external_locations WHERE table_name LIKE '%TOP_AGGREGATED_ALLOTMENT%' AND owner IN ('ODS', 'CT_MRDS') ORDER BY owner, table_name; ``` ### Test 2: Próba dostępu do danych ```sql -- Test ODS (pliki CSV) SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS; -- Test pierwszych 5 rekordów SELECT * FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS WHERE ROWNUM <= 5; ``` ### Test 3: Weryfikacja ARCHIVE (pliki PARQUET) ```sql -- Test ARCHIVE (pliki PARQUET z partycjonowaniem) SELECT COUNT(*) FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE; -- Sprawdzenie partycji SELECT DISTINCT year, month FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE ORDER BY year, month; ``` ## 📊 Struktura plików w buckets ### Data bucket (ODS) - format CSV ``` data/ └── ODS/ └── TOP/ └── AGGREGATED_ALLOTMENT/ ├── AGGREGATED_ALLOTMENT_202508_1_*.csv ├── AGGREGATED_ALLOTMENT_202508_2_*.csv ├── AGGREGATED_ALLOTMENT_202509_1_*.csv └── ... (14 plików CSV) ``` ### History bucket (ARCHIVE) - format PARQUET z partycjonowaniem Hive ``` history/ └── TOP/ └── AGGREGATED_ALLOTMENT/ └── YEAR=2025/ ├── MONTH=08/ │ ├── 202508_1_*.parquet │ ├── 202508_2_*.parquet │ ├── 202508_3_*.parquet │ └── 202508_4_*.parquet └── MONTH=09/ ├── 202509_1_*.parquet ├── 202509_2_*.parquet ├── 202509_3_*.parquet └── 202509_4_*.parquet ``` ## ⚠️ Uwagi dotyczące FILE_MANAGER ### Automatyczna detekcja formatu Pakiet `FILE_MANAGER.CREATE_EXTERNAL_TABLE` automatycznie wykrywa format na podstawie `pBucketUri`: - **Jeśli** `pBucketUri` zawiera `gvArchiveBucketUri` → format PARQUET z partycjonowaniem Hive - **Jeśli** `pBucketUri` zawiera `gvDataBucketUri` lub `gvInboxBucketUri` → format CSV ### Konfiguracja środowiska ```sql -- Sprawdzenie konfiguracji ENV_MANAGER SET SERVEROUTPUT ON; DECLARE v_inbox VARCHAR2(4000); v_data VARCHAR2(4000); v_history VARCHAR2(4000); BEGIN v_inbox := CT_MRDS.ENV_MANAGER.gvInboxBucketUri; v_data := CT_MRDS.ENV_MANAGER.gvDataBucketUri; v_history := CT_MRDS.ENV_MANAGER.gvArchiveBucketUri; DBMS_OUTPUT.PUT_LINE('Inbox: ' || v_inbox); DBMS_OUTPUT.PUT_LINE('Data: ' || v_data); DBMS_OUTPUT.PUT_LINE('History: ' || v_history); END; / ``` ## 🎯 Zalecane działania ### Krok 1: Nadaj uprawnienia (NAJSZYBSZE) ```sql -- Jako ADMIN lub z uprawnieniami GRANT GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_ODS TO CT_MRDS; GRANT SELECT ON ODS.TOP_AGGREGATED_ALLOTMENT_INBOX TO CT_MRDS; ``` ### Krok 2: Przebuduj ARCHIVE table ```sql -- Jako ODS user DROP TABLE TOP_AGGREGATED_ALLOTMENT_ARCHIVE; BEGIN FILE_MANAGER_ODS.CREATE_EXTERNAL_TABLE( pTableName => 'TOP_AGGREGATED_ALLOTMENT_ARCHIVE', pTemplateTableName => 'CT_ET_TEMPLATES.TOP_AGGREGATED_ALLOTMENT', pPrefix => 'TOP/AGGREGATED_ALLOTMENT', pBucketUri => CT_MRDS.ENV_MANAGER.gvArchiveBucketUri ); END; / -- Nadaj uprawnienia GRANT SELECT ON TOP_AGGREGATED_ALLOTMENT_ARCHIVE TO CT_MRDS; ``` ### Krok 3: Test końcowy ```sql -- Z schematu CT_MRDS SELECT 'ODS' as source, COUNT(*) as row_count FROM ODS.TOP_AGGREGATED_ALLOTMENT_ODS UNION ALL SELECT 'ARCHIVE' as source, COUNT(*) as row_count FROM ODS.TOP_AGGREGATED_ALLOTMENT_ARCHIVE; ``` Teraz external tables powinny działać poprawnie! 🎉