Blog Name
  • Februar 2019

Autonomous Database Services: Komprimierte Dateien einbinden

Die Thematik des Ladevorgangs von Daten aus einem Object Storage in die Autonomous Database haben wir bereits in einem älteren Beitrag mit Data Pump Import adressiert. Zur Erinnerung: Bewerkstelligen lässt sich ein Data Pump Import in die Autonomous Database dabei entweder graphisch über die SQL Developer Schnittstelle oder aber auch über einen Data Pump Instant Client, den man sich lokal kopieren kann. Genaueres dazu findet sich im Beitrag Autonomous Data Warehouse Cloud: So geht's. Übrigens sind die dort beschriebenen Vorgehensweisen auch ohne Weiteres auf den Autonomous Transaction Processing Service (ATP) übertragbar.

Einige Kunden stellten uns in letzter Zeit die Frage, ob man auch komprimierte Dateien beispielsweise im Format GZ, TAR etc über den Object Storage laden bzw. ansprechen kann. Die Antwort darauf liefert das Package DBMS_CLOUD, das eine spezielle Unterstützung für komprimierte Daten liefert. Es ist damit möglich entweder die Daten direkt in eine bestehende Tabelle zu laden oder die Daten einfach im Object Storage zu belassen und über eine External Table zuzugreifen.

Um das Ganze einfach zu demonstrieren, verwenden wir eine kleine Datei (hier CHANNELS.gz) im .gz Format. Diese besteht nur aus ein paar Zeilen, die durch das Zeichen '|' getrennt sind. Unkomprimiert handelt es sich dabei um folgenden Inhalte:

S|Direct Sales|Direct
T|Tele Sales|Direct
C|Catalog|Indirect
I|Internet|Indirect
P|Partners|Others

Wer dies selbst nachvollziehen möchte, kann die Datei CHANNELS.gz hier herunterladen und danach in den eigenen Object Storage laden.

Wie beim Laden von Daten mit Data Pump muss auch in diesem Fall gewährleistet sein, dass die Kommunikation mit der Autonomous Database abgesichert ist und nur autorisierte Daten geladen werden. Dazu werden die Datenbank Credentials mit dem Package DBMS_CLOUD angelegt und als Default festgelegt. Das verwendete Passwort lässt sich in der OCI Konsole oben rechts unter "User Settings" im Bereich Auth Tokens mit Generate Token erzeugen. Die Database Credentials lauten in meinem Fall CREDENTIAL_US1. Verbinden wir uns einfach mit dem SQL Developer und setzen dazu folgende Befehle ab.

execute dbms_cloud.drop_credential('CREDENTIAL_US1');
begin DBMS_CLOUD.create_credential(credential_name => 'CREDENTIAL_US1',
                                          username => 'oracleidentitycloudservice/ulrike.schwinn@oracle.com',
                                          password => 'AUTH Token passwort');

end;
/
alter database property set default_credential = 'ADMIN.CREDENTIAL_US1';

Im Beispiel verwende ich einen Federated User, der vollqualifiziert angegeben werden muss inklusive Identity Provider (IdP)- also zum Beispiel oracleidentitycloudservice/ulrike.schwinn@oracle.com. Das Ganze funktioniert natürlich ebenso mit einem lokalen User.


Zugriff mit External Table

Um einen Zugriff über eine External Table zu ermöglichen, verwenden wir die Funktion CREATE_EXTERNAL_TABLE des Package DBMS_CLOUD. Eine genaue Beschreibung des Package DBMS_CLOUD findet man übrigens in der Dokumentation.

Zur Ausführung wird dann der Tabellenname (hier CHANNELS_TXT), der Credential Name (hier CREDENTIAL_US1), die FILE_URI_LIST (kurz für Uniform Resource Identifier), das Argument FORMAT und das Argument COLUMN_LIST, das die Liste der Spaltennamen und Datentypen, durch Kommata getrennt, für die externe Tabelle angibt, benötigt. Der Parameter FORMAT enthält dabei eine spezielle Option COMPRESSION für komprimierte Dateien. Wichtig bei der Verwendung des FORMAT Parameters ist auch die korrekte Angabe der Delimiter. Folgendes Beispiel zeigt die Verwendung.

drop table CHANNELS_EXT;

begin DBMS_CLOUD.create_external_table(table_name=>'CHANNELS_EXT', 
                      credential_name => 'CREDENTIAL_US1',
                      file_uri_list => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/USBUCKET/o/CHANNELS.gz',
                      format => json_object('compression' value 'auto','delimiter' value '|' ),
                      column_list=>'CHANNEL_SBORT Varchar2(1),
                      Channel_long varchar2(20),
                      channel_class varchar2(20)');
                      end;
/

Hinweis: Der Parameter FORMAT kann in zwei verschiedenen Varianten angegeben werden:
format => '{"format_option" : "format_value" }'
oder
format => json_object('format_option' value 'format_value'))
Ich habe die letzte Variante verwendet.

Die Optionen für das Argument FORMAT sind in der Dokumentation im Abschnitt DBMS_CLOUD Package Format Options zu finden.

Nun werden die Daten der External Tabelle ausgegeben. Folgender Screenshot zeigt das Ergebnis.



Hinweis: Übrigens lassen sich mit dem Argument FORMAT auch Parquet Files laden. Eine genaue Beschreibung dazu findet sich im Handbuch in Table A-1 DBMS_CLOUD Parquet File Format Options. Eine gute Anleitung zum Laden von Parquet Files findet sich in folgendem Blogeintrag Oracle Autonomous Data Warehouse - Access Parquet Files in Object Stores.

Laden von Daten

Die Daten lassen sich auch in eine Datenbank Tabelle laden. Dazu legen wir eine entsprechende Tabelle CHANNELS an.

drop table channels;

CREATE TABLE CHANNELS
   (channel_id char(1),
    channel_desc varchar2(20),
    channel_class varchar2(20)
   );

Das Package DBMS_CLOUD liefert mit COPY_DATA für diese Anforderung ein Funktion. Dabei verwenden wir die Credentials von oben. COPY_DATA steuert auch hier mit dem Parameter FORMAT und der Option COMPRESSION die Verwendung von komprimierten Dateien. Das Argument FIELD_LIST entspricht dabei der FIELD_LIST Klausel in regulären externen Oracle Tables - siehe auch die Dokumentation dazu. Folgendes Beispiel zeigt dann die Verwendung.

begin DBMS_CLOUD.copy_data(table_name=>'CHANNELS', 
                      credential_name => 'CREDENTIAL_US1',
                      file_uri_list => 'https://objectstorage.eu-frankfurt-1.oraclecloud.com/n/oraseemeadesandbox/b/USBUCKET/o/CHANNELS.gz',
                      format => '{"compression":"auto", "delimiter":"|"}',
         field_list=>'channel_id char(1),
                      channel_desc char(50),
                      channel_class char(50)');
                      end;
                      /

Und fertig! Folgender Screenshot zeigt das Ergebnis.

Weitere Informationen

 

Zurück zur Community-Seite
 

Visit the Oracle Blog

 

Contact Us

Oracle

Integrated Cloud Applications & Platform Services