UTLFILEOracle_-Funktionalität auf Aurora SQL Postgre-Compatible einrichten - AWS Prescriptive Guidance

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

UTLFILEOracle_-Funktionalität auf Aurora SQL Postgre-Compatible einrichten

Erstellt von Rakesh Raghav (AWS) und Anuradha Chintha () AWS

Umgebung: PoC oder Pilotprojekt

Quelle: Oracle

Ziel: Aurora Postgre SQL

R-Typ: Re-Architect

Arbeitslast: Oracle

Technologien: Migration; Infrastruktur; Datenbanken

AWSDienste: Amazon S3; Amazon Aurora

Übersicht

Im Rahmen Ihrer Migration von Oracle zu Amazon Aurora SQL Postgre-Compatible Edition in der Amazon Web Services (AWS) Cloud können Sie auf mehrere Herausforderungen stoßen. Beispielsweise ist die Migration von Code, der auf dem UTL_FILE Oracle-Hilfsprogramm basiert, immer eine Herausforderung. In Oracle PL/ SQL wird das UTL_FILE Paket in Verbindung mit dem zugrunde liegenden Betriebssystem für Dateioperationen wie Lesen und Schreiben verwendet. Das UTL_FILE Hilfsprogramm funktioniert sowohl für Server- als auch für Client-Computersysteme. 

Amazon Aurora SQL Postgre-Compatible ist ein Angebot für verwaltete Datenbanken. Aus diesem Grund ist es nicht möglich, auf Dateien auf dem Datenbankserver zuzugreifen. Dieses Muster führt Sie durch die Integration von Amazon Simple Storage Service (Amazon S3) und Amazon Aurora SQL Postgre-Compatible, um einen Teil der Funktionen zu erreichen. UTL_FILE Mit dieser Integration können wir Dateien erstellen und verwenden, ohne Tools oder Dienste von Drittanbietern zum Extrahieren, Transformieren und Laden (ETL) verwenden zu müssen.

Optional können Sie CloudWatch Amazon-Überwachung und SNS Amazon-Benachrichtigungen einrichten.

Wir empfehlen, diese Lösung gründlich zu testen, bevor Sie sie in einer Produktionsumgebung implementieren.

Voraussetzungen und Einschränkungen

Voraussetzungen

  • Ein aktives AWS Konto

  • AWSFachwissen zum Database Migration Service (AWSDMS)

  • Fachkenntnisse in der PL/PG-Codierung SQL

  • Ein Amazon Aurora SQL Postgre-kompatibler Cluster

  • Ein S3-Bucket

Einschränkungen

Dieses Muster bietet nicht die Funktionalität, um das UTL_FILE Oracle-Hilfsprogramm zu ersetzen. Die Schritte und der Beispielcode können jedoch weiter verbessert werden, um Ihre Ziele bei der Datenbankmodernisierung zu erreichen.

Produktversionen

  • Amazon Aurora SQL Postgre-Kompatible Ausgabe 11.9

Architektur

Zieltechnologie-Stack

  • Amazon Aurora Postgre-kompatibel SQL

  • Amazon CloudWatch

  • Amazon Simple Notification Service (AmazonSNS)

  • Amazon S3

Zielarchitektur

Das folgende Diagramm zeigt eine allgemeine Darstellung der Lösung.

Datendateien werden in einen S3-Bucket hochgeladen, mit der Erweiterung aws_s3 verarbeitet und an die Aurora-Instance gesendet.
  1. Dateien werden aus der Anwendung in den S3-Bucket hochgeladen.

  2. Die aws_s3 Erweiterung greift mithilfe von PL/Pg SQL auf die Daten zu und lädt die Daten auf Aurora Postgre-Compatible hoch. SQL

Tools

  • Amazon Aurora Postgre SQL -Compatible — Amazon Aurora Postgre SQL -Compatible Edition ist eine vollständig verwaltete, Postgre-kompatible und SQL -konforme relationale Datenbank-Engine. ACID Sie kombiniert die Geschwindigkeit und Zuverlässigkeit kommerzieller High-End-Datenbanken mit der Kosteneffizienz von Open-Source-Datenbanken.

  • AWSCLI— Die AWS Befehlszeilenschnittstelle (AWSCLI) ist ein einheitliches Tool zur Verwaltung Ihrer AWS Dienste. Da Sie nur ein Tool herunterladen und konfigurieren müssen, können Sie mehrere AWS Dienste von der Befehlszeile aus steuern und mithilfe von Skripten automatisieren.

  • Amazon CloudWatch — Amazon CloudWatch überwacht die Ressourcen und die Nutzung von Amazon S3.

  • Amazon S3 — Amazon Simple Storage Service (Amazon S3) ist ein Speicher für das Internet. In diesem Muster bietet Amazon S3 eine Speicherebene zum Empfangen und Speichern von Dateien für den Verbrauch und die Übertragung zum und vom Aurora SQL Postgre-kompatiblen Cluster.

  • aws_s3 — Die aws_s3 Erweiterung integriert Amazon S3 und Aurora SQL Postgre-Compatible.

  • Amazon SNS — Amazon Simple Notification Service (AmazonSNS) koordiniert und verwaltet die Zustellung oder den Versand von Nachrichten zwischen Herausgebern und Kunden. In diesem Muster SNS wird Amazon zum Senden von Benachrichtigungen verwendet.

  • pgAdmin— pgAdmin ist ein Open-Source-Verwaltungstool für Postgres. pgAdmin 4 bietet eine grafische Oberfläche zum Erstellen, Verwalten und Verwenden von Datenbankobjekten.

Code

Um die erforderliche Funktionalität zu erreichen, erstellt das Muster mehrere Funktionen mit einer ähnlichen Benennung wieUTL_FILE. Der Abschnitt Zusätzliche Informationen enthält die Codebasis für diese Funktionen.

Ersetzen Sie den Code testaurorabucket durch den Namen Ihres Test-S3-Buckets. us-east-1Ersetzen Sie es durch die AWS Region, in der sich Ihr Test-S3-Bucket befindet.

Epen

AufgabeBeschreibungErforderliche Fähigkeiten
Richten Sie IAM Richtlinien ein.

Erstellen Sie Richtlinien für das AWS Identity and Access Management (IAM), die Zugriff auf den S3-Bucket und die darin enthaltenen Objekte gewähren. Den Code finden Sie im Abschnitt Zusätzliche Informationen.

AWSAdministrator, DBA
Fügen Sie Amazon S3 S3-Zugriffsrollen zu Aurora Postgre SQL hinzu.

Erstellen Sie zwei IAM Rollen: eine Rolle für den Lese- und eine Rolle für den Schreibzugriff auf Amazon S3. Hängen Sie die beiden Rollen an den Aurora SQL Postgre-Compatible Cluster an: 

  • Eine Rolle für die S3Export-Funktion

  • Eine Rolle für die S3Import-Funktion

Weitere Informationen finden Sie in der Aurora SQL Postgre-kompatiblen Dokumentation zum Import und Export von Daten nach Amazon S3.

AWSAdministrator, DBA
AufgabeBeschreibungErforderliche Fähigkeiten
Erstellen Sie die Erweiterung aws_commons.

Die aws_commons Erweiterung ist eine Abhängigkeit von der aws_s3 Erweiterung.

DBA, Entwickler
Erstellen Sie die Erweiterung aws_s3.

Die aws_s3 Erweiterung interagiert mit Amazon S3.

DBA, Entwickler
AufgabeBeschreibungErforderliche Fähigkeiten
Testen Sie den Import von Dateien aus Amazon S3 in Aurora PostgreSQL.

Um den Import von Dateien in Aurora SQL Postgre-Compatible zu testen, erstellen Sie eine CSV Beispieldatei und laden Sie sie in den S3-Bucket hoch. Erstellen Sie eine auf der CSV Datei basierende Tabellendefinition und laden Sie die Datei mithilfe der Funktion in die aws_s3.table_import_from_s3 Tabelle.

DBA, Entwickler
Testen Sie den Export von Dateien von Aurora Postgre SQL nach Amazon S3.

Um den Export von Dateien aus Aurora Postgre SQL -Compatible zu testen, erstellen Sie eine Testtabelle, füllen Sie sie mit Daten und exportieren Sie die Daten dann mithilfe der Funktion. aws_s3.query_export_to_s3

DBA, Entwickler
AufgabeBeschreibungErforderliche Fähigkeiten
Erstellen Sie das Schema utl_file_utility.

Das Schema hält die Wrapper-Funktionen zusammen. Führen Sie den folgenden Befehl aus, um das Schema zu erstellen.

CREATE SCHEMA utl_file_utility;
DBA, Entwickler
Erstellen Sie den Typ file_type.

Verwenden Sie den folgenden Code, um den file_type Typ zu erstellen.

CREATE TYPE utl_file_utility.file_type AS (     p_path character varying(30),     p_file_name character varying );
DBA/Entwickler
Erstellen Sie die Init-Funktion.

Die init Funktion initialisiert eine gemeinsame Variable wie oder. bucket region Den Code finden Sie im Abschnitt Zusätzliche Informationen.

DBA/Entwickler
Erstellen Sie die Wrapper-Funktionen.

Erstellen Sie die Wrapper-Funktionen fopenput_line, und. fclose Code finden Sie im Abschnitt Zusätzliche Informationen.

DBA, Entwickler
AufgabeBeschreibungErforderliche Fähigkeiten
Testen Sie die Wrapper-Funktionen im Schreibmodus.

Um die Wrapper-Funktionen im Schreibmodus zu testen, verwenden Sie den Code im Abschnitt Zusätzliche Informationen.

DBA, Entwickler
Testen Sie die Wrapper-Funktionen im Append-Modus.

Um die Wrapper-Funktionen im Append-Modus zu testen, verwenden Sie den Code im Abschnitt Zusätzliche Informationen.

DBA, Entwickler

Zugehörige Ressourcen

Zusätzliche Informationen

Richten Sie IAM Richtlinien ein

Erstellen Sie die folgenden Richtlinien.

Name der Richtlinie

JSON

S3 IntRead

{     "Version": "2012-10-17",     "Statement": [         {             "Sid": "S3integrationtest",             "Effect": "Allow",             "Action": [                 "s3:GetObject",                 "s3:ListBucket"             ],             "Resource": [          "arn:aws:s3:::testaurorabucket/*",          "arn:aws:s3:::testaurorabucket"             ]         }     ] }

S 3 IntWrite

{     "Version": "2012-10-17",     "Statement": [         {             "Sid": "S3integrationtest",             "Effect": "Allow",             "Action": [                 "s3:PutObject",                                 "s3:ListBucket"             ],             "Resource": [                "arn:aws:s3:::testaurorabucket/*",                "arn:aws:s3:::testaurorabucket"             ]         }     ] }

Erstellen Sie die Init-Funktion

Um allgemeine Variablen wie bucket oder zu initialisierenregion, erstellen Sie die init Funktion mit dem folgenden Code.

CREATE OR REPLACE FUNCTION utl_file_utility.init(     )     RETURNS void     LANGUAGE 'plpgsql'     COST 100     VOLATILE AS $BODY$ BEGIN       perform set_config       ( format( '%s.%s','UTL_FILE_UTILITY', 'region' )       , 'us-east-1'::text       , false );       perform set_config       ( format( '%s.%s','UTL_FILE_UTILITY', 's3bucket' )       , 'testaurorabucket'::text       , false ); END; $BODY$;

Erstellen Sie die Wrapper-Funktionen

Erstellen Sie die fclose Wrapper-Funktionen fopenput_line, und.

öffnen

CREATE OR REPLACE FUNCTION utl_file_utility.fopen(     p_file_name character varying,     p_path character varying,     p_mode character DEFAULT 'W'::bpchar,     OUT p_file_type utl_file_utility.file_type)     RETURNS utl_file_utility.file_type     LANGUAGE 'plpgsql'     COST 100     VOLATILE AS $BODY$ declare     v_sql character varying;     v_cnt_stat integer;     v_cnt integer;     v_tabname character varying;     v_filewithpath character varying;     v_region character varying;     v_bucket character varying; BEGIN     /*initialize common variable */     PERFORM utl_file_utility.init();     v_region := current_setting( format( '%s.%s', 'UTL_FILE_UTILITY', 'region' ) );     v_bucket :=  current_setting( format( '%s.%s', 'UTL_FILE_UTILITY', 's3bucket' ) );         /* set tabname*/     v_tabname := substring(p_file_name,1,case when strpos(p_file_name,'.') = 0 then length(p_file_name) else strpos(p_file_name,'.') - 1 end );     v_filewithpath := case when NULLif(p_path,'') is null then p_file_name else concat_ws('/',p_path,p_file_name) end ;     raise notice 'v_bucket %, v_filewithpath % , v_region %', v_bucket,v_filewithpath, v_region;         /* APPEND MODE HANDLING; RETURN EXISTING FILE DETAILS IF PRESENT ELSE CREATE AN EMPTY FILE */     IF p_mode = 'A' THEN         v_sql := concat_ws('','create temp table if not exists ', v_tabname,' (col1 text)');         execute v_sql;         begin         PERFORM aws_s3.table_import_from_s3             ( v_tabname,             '',               'DELIMITER AS ''#''',             aws_commons.create_s3_uri             (     v_bucket,                 v_filewithpath ,                 v_region)             );         exception             when others then              raise notice 'File load issue ,%',sqlerrm;              raise;         end;         execute concat_ws('','select count(*) from ',v_tabname) into v_cnt;         IF v_cnt > 0         then             p_file_type.p_path := p_path;             p_file_type.p_file_name := p_file_name;         else                     PERFORM aws_s3.query_export_to_s3('select ''''',                             aws_commons.create_s3_uri(v_bucket, v_filewithpath, v_region)                                           );             p_file_type.p_path := p_path;             p_file_type.p_file_name := p_file_name;                 end if;         v_sql := concat_ws('','drop table ', v_tabname);                 execute v_sql;                 ELSEIF p_mode = 'W' THEN             PERFORM aws_s3.query_export_to_s3('select ''''',                             aws_commons.create_s3_uri(v_bucket, v_filewithpath, v_region)                                           );             p_file_type.p_path := p_path;             p_file_type.p_file_name := p_file_name;     END IF;         EXCEPTION         when others then             p_file_type.p_path := p_path;             p_file_type.p_file_name := p_file_name;             raise notice 'fopenerror,%',sqlerrm;             raise; END; $BODY$;

put_line

CREATE OR REPLACE FUNCTION utl_file_utility.put_line(     p_file_name character varying,     p_path character varying,     p_line text,     p_flag character DEFAULT 'W'::bpchar)     RETURNS boolean     LANGUAGE 'plpgsql'     COST 100     VOLATILE AS $BODY$ /************************************************************************** * Write line, p_line in windows format to file, p_fp - with carriage return * added before new line. **************************************************************************/ declare     v_sql varchar;     v_ins_sql varchar;     v_cnt INTEGER;     v_filewithpath character varying;     v_tabname  character varying;     v_bucket character varying;     v_region character varying;     BEGIN  PERFORM utl_file_utility.init(); /* check if temp table already exist */  v_tabname := substring(p_file_name,1,case when strpos(p_file_name,'.') = 0 then length(p_file_name) else strpos(p_file_name,'.') - 1 end );  v_sql := concat_ws('','select count(1) FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace where n.nspname like ''pg_temp_%'''                          ,' AND pg_catalog.pg_table_is_visible(c.oid) AND Upper(relname) = Upper( '''                          ,  v_tabname ,''' ) ');    execute v_sql into v_cnt;     IF v_cnt = 0 THEN          v_sql := concat_ws('','create temp table ',v_tabname,' (col text)');         execute v_sql;         /* CHECK IF APPEND MODE */         IF upper(p_flag) = 'A' THEN             PERFORM utl_file_utility.init();                                     v_region := current_setting( format( '%s.%s', 'UTL_FILE_UTILITY', 'region' ) );             v_bucket :=  current_setting( format( '%s.%s', 'UTL_FILE_UTILITY', 's3bucket' ) );                         /* set tabname*/                         v_filewithpath := case when NULLif(p_path,'') is null then p_file_name else concat_ws('/',p_path,p_file_name) end ;                                     begin                PERFORM aws_s3.table_import_from_s3                      ( v_tabname,                           '',                          'DELIMITER AS ''#''',                         aws_commons.create_s3_uri                            ( v_bucket,                                v_filewithpath,                                v_region    )                     );             exception                 when others then                     raise notice  'Error Message : %',sqlerrm;                     raise;             end;             END IF;         END IF;     /* INSERT INTO TEMP TABLE */                   v_ins_sql := concat_ws('','insert into ',v_tabname,' values(''',p_line,''')');     execute v_ins_sql;     RETURN TRUE;     exception             when others then                 raise notice  'Error Message : %',sqlerrm;                 raise; END; $BODY$;

schließen

CREATE OR REPLACE FUNCTION utl_file_utility.fclose(     p_file_name character varying,     p_path character varying)     RETURNS boolean     LANGUAGE 'plpgsql'     COST 100     VOLATILE AS $BODY$ DECLARE     v_filewithpath character varying;     v_bucket character varying;     v_region character varying;     v_tabname character varying; v_sql character varying; BEGIN       PERFORM utl_file_utility.init();       v_region := current_setting( format( '%s.%s', 'UTL_FILE_UTILITY', 'region' ) );     v_bucket :=  current_setting( format( '%s.%s', 'UTL_FILE_UTILITY', 's3bucket' ) );     v_tabname := substring(p_file_name,1,case when strpos(p_file_name,'.') = 0 then length(p_file_name) else strpos(p_file_name,'.') - 1 end );     v_filewithpath := case when NULLif(p_path,'') is null then p_file_name else concat_ws('/',p_path,p_file_name) end ;     raise notice 'v_bucket %, v_filewithpath % , v_region %', v_bucket,v_filewithpath, v_region ;         /* exporting to s3 */     perform aws_s3.query_export_to_s3         (concat_ws('','select * from ',v_tabname,'  order by ctid asc'),             aws_commons.create_s3_uri(v_bucket, v_filewithpath, v_region)         );    v_sql := concat_ws('','drop table ', v_tabname);     execute v_sql;        RETURN TRUE; EXCEPTION        when others then      raise notice 'error fclose %',sqlerrm;      RAISE; END; $BODY$;

Testen Sie Ihr Setup und Ihre Wrapper-Funktionen

Verwenden Sie die folgenden anonymen Codeblöcke, um Ihr Setup zu testen.

Testen Sie den Schreibmodus

Der folgende Code schreibt eine Datei mit dem Namen s3inttest im S3-Bucket.

do $$ declare l_file_name varchar := 's3inttest' ; l_path varchar := 'integration_test' ; l_mode char(1) := 'W'; l_fs utl_file_utility.file_type ; l_status boolean; begin select * from utl_file_utility.fopen( l_file_name, l_path , l_mode ) into l_fs ; raise notice 'fopen : l_fs : %', l_fs; select * from utl_file_utility.put_line( l_file_name, l_path ,'this is test file:in s3bucket: for test purpose', l_mode ) into l_status ; raise notice 'put_line : l_status %', l_status; select * from utl_file_utility.fclose( l_file_name , l_path ) into l_status ; raise notice 'fclose : l_status %', l_status; end; $$

Testen Sie den Append-Modus

Der folgende Code fügt Zeilen an die s3inttest Datei an, die im vorherigen Test erstellt wurde.

do $$ declare l_file_name varchar := 's3inttest' ; l_path varchar := 'integration_test' ; l_mode char(1) := 'A'; l_fs utl_file_utility.file_type ; l_status boolean; begin select * from utl_file_utility.fopen( l_file_name, l_path , l_mode ) into l_fs ; raise notice 'fopen : l_fs : %', l_fs; select * from utl_file_utility.put_line( l_file_name, l_path ,'this is test file:in s3bucket: for test purpose : append 1', l_mode ) into l_status ; raise notice 'put_line : l_status %', l_status; select * from utl_file_utility.put_line( l_file_name, l_path ,'this is test file:in s3bucket : for test purpose : append 2', l_mode ) into l_status ; raise notice 'put_line : l_status %', l_status; select * from utl_file_utility.fclose( l_file_name , l_path ) into l_status ; raise notice 'fclose : l_status %', l_status; end; $$

SNSAmazon-Benachrichtigungen

Optional können Sie CloudWatch Amazon-Überwachung und SNS Amazon-Benachrichtigungen im S3-Bucket einrichten. Weitere Informationen finden Sie unter Amazon S3 überwachen und SNSAmazon-Benachrichtigungen einrichten.