Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.
Siapkan fungsionalitas Oracle UTL_FILE pada Aurora PostgreSQL yang kompatibel
Rakesh Raghav dan anuradha chintha, Amazon Web Services
Ringkasan
Sebagai bagian dari perjalanan migrasi Anda dari Oracle ke Amazon Aurora PostgreSQL Compatible Edition di Amazon Web Services (AWS) Cloud, Anda mungkin menghadapi beberapa tantangan. Misalnya, memigrasikan kode yang bergantung pada UTL_FILE utilitas Oracle selalu menjadi tantangan. Di Oracle PL/SQL, UTL_FILE paket ini digunakan untuk operasi file, seperti baca dan tulis, bersama dengan sistem operasi yang mendasarinya. UTL_FILEUtilitas ini berfungsi untuk sistem server dan mesin klien.
Amazon Aurora PostgreSQL kompatibel adalah penawaran database terkelola. Karena itu, tidak mungkin mengakses file di server database. Pola ini memandu Anda melalui integrasi Amazon Simple Storage Service (Amazon S3) dan Amazon Aurora PostgreSQL yang kompatibel untuk mencapai subset fungsionalitas. UTL_FILE Dengan menggunakan integrasi ini, kita dapat membuat dan menggunakan file tanpa menggunakan alat atau layanan ekstrak, transformasi, dan muat (ETL) pihak ketiga.
Secara opsional, Anda dapat mengatur CloudWatch pemantauan Amazon dan notifikasi Amazon SNS.
Kami merekomendasikan pengujian solusi ini secara menyeluruh sebelum menerapkannya di lingkungan produksi.
Prasyarat dan batasan
Prasyarat
Akun AWS yang aktif
Keahlian AWS Database Migration Service (AWS DMS)
Keahlian dalam PL/pgSQL pengkodean
Cluster yang kompatibel dengan Amazon Aurora PostgreSQL
Ember S3
Batasan
Pola ini tidak menyediakan fungsionalitas untuk bertindak sebagai pengganti UTL_FILE utilitas Oracle. Namun, langkah-langkah dan kode sampel dapat ditingkatkan lebih lanjut untuk mencapai tujuan modernisasi database Anda.
Versi produk
Amazon Aurora PostgreSQL Edisi 11.9 yang kompatibel
Arsitektur
Tumpukan teknologi target
Kompatibel dengan Amazon Aurora PostgreSQL
Amazon CloudWatch
Amazon Simple Notification Service (Amazon SNS)
Amazon S3
Arsitektur target
Diagram berikut menunjukkan representasi tingkat tinggi dari solusi.

File diunggah dari aplikasi ke dalam ember S3.
aws_s3Ekstensi mengakses data, menggunakan PL/PGSQL, dan mengunggah data ke Aurora PostgreSQL kompatibel.
Alat
Kompatibel dengan Amazon Aurora PostgreSQL — Amazon Aurora PostgreSQL Compatible Edition adalah mesin basis data relasional yang dikelola sepenuhnya, kompatibel dengan PostgreSQL, dan sesuai dengan Asam. Ini menggabungkan kecepatan dan keandalan database komersial kelas atas dengan efektivitas biaya database sumber terbuka.
AWS CLI — AWS Command Line Interface (AWS CLI) Command Line Interface (AWS CLI) adalah alat terpadu untuk mengelola layanan AWS Anda. Dengan hanya satu alat untuk mengunduh dan mengonfigurasi, Anda dapat mengontrol beberapa layanan AWS dari baris perintah dan mengotomatiskannya melalui skrip.
Amazon CloudWatch — Amazon CloudWatch memonitor sumber daya dan penggunaan Amazon S3.
Amazon S3 - Amazon Simple Storage Service (Amazon S3) Simple Storage Service adalah penyimpanan untuk internet. Dalam pola ini, Amazon S3 menyediakan lapisan penyimpanan untuk menerima dan menyimpan file untuk konsumsi dan transmisi ke dan dari cluster Aurora PostgreSQL yang kompatibel.
aws_s3 - Ekstensi
aws_s3mengintegrasikan Amazon S3 dan Aurora PostgreSQL kompatibel.Amazon SNS - Amazon Simple Notification Service (Amazon SNS) mengoordinasikan dan mengelola pengiriman atau pengiriman pesan antara penerbit dan klien. Dalam pola ini, Amazon SNS digunakan untuk mengirim notifikasi.
pgAdmin
- pgAdmin adalah alat manajemen sumber terbuka untuk Postgres. pgAdmin 4 menyediakan antarmuka grafis untuk membuat, memelihara, dan menggunakan objek database.
Kode
Untuk mencapai fungsionalitas yang diperlukan, pola membuat beberapa fungsi dengan penamaan yang mirip denganUTL_FILE. Bagian Informasi tambahan berisi basis kode untuk fungsi-fungsi ini.
Dalam kode, ganti testaurorabucket dengan nama bucket S3 pengujian Anda. Ganti us-east-1 dengan Wilayah AWS tempat bucket S3 pengujian Anda berada.
Epik
| Tugas | Deskripsi | Keterampilan yang dibutuhkan |
|---|---|---|
| Siapkan kebijakan IAM. | Buat kebijakan AWS Identity and Access Management (IAM) yang memberikan akses ke bucket S3 dan objek di dalamnya. Untuk kode, lihat bagian Informasi tambahan. | Administrator AWS, DBA |
| Tambahkan peran akses Amazon S3 ke Aurora PostgreSQL. | Buat dua peran IAM: satu peran untuk dibaca dan satu peran untuk akses tulis ke Amazon S3. Lampirkan dua peran ke cluster yang kompatibel dengan Aurora PostgreSQL:
Untuk informasi selengkapnya, lihat dokumentasi yang kompatibel dengan Aurora PostgreSQL tentang mengimpor dan mengekspor data ke Amazon S3. | Administrator AWS, DBA |
| Tugas | Deskripsi | Keterampilan yang dibutuhkan |
|---|---|---|
| Buat ekstensi aws_commons. |
| DBA, Pengembang |
| Buat ekstensi aws_s3. |
| DBA, Pengembang |
| Tugas | Deskripsi | Keterampilan yang dibutuhkan |
|---|---|---|
| Uji mengimpor file dari Amazon S3 ke Aurora PostgreSQL. | Untuk menguji mengimpor file ke Aurora PostgreSQL yang kompatibel, buat contoh file CSV dan unggah ke bucket S3. Buat definisi tabel berdasarkan file CSV, dan muat file ke dalam tabel dengan menggunakan | DBA, Pengembang |
| Uji ekspor file dari Aurora PostgreSQL ke Amazon S3. | Untuk menguji mengekspor file dari Aurora PostgreSQL yang kompatibel, buat tabel uji, isi dengan data, lalu ekspor data dengan menggunakan fungsi. | DBA, Pengembang |
| Tugas | Deskripsi | Keterampilan yang dibutuhkan |
|---|---|---|
| Buat skema utl_file_utility. | Skema menjaga fungsi pembungkus bersama-sama. Untuk membuat skema, jalankan perintah berikut.
| DBA, Pengembang |
| Buat tipe file_type. | Untuk membuat
| DBA/Pengembang |
| Buat fungsi init. |
| DBA/Pengembang |
| Buat fungsi pembungkus. | Buat fungsi pembungkus | DBA, Pengembang |
| Tugas | Deskripsi | Keterampilan yang dibutuhkan |
|---|---|---|
| Uji fungsi pembungkus dalam mode tulis. | Untuk menguji fungsi pembungkus dalam mode tulis, gunakan kode yang disediakan di bagian Informasi tambahan. | DBA, Pengembang |
| Uji fungsi pembungkus dalam mode append. | Untuk menguji fungsi pembungkus dalam mode append, gunakan kode yang disediakan di bagian Informasi tambahan. | DBA, Pengembang |
Sumber daya terkait
Informasi tambahan
Menyiapkan kebijakan IAM
Buat kebijakan berikut.
Nama kebijakan | JSON |
|---|---|
S3 IntRead |
|
S3 IntWrite |
|
Buat fungsi init
Untuk menginisialisasi variabel umum, seperti bucket atauregion, buat init fungsi dengan menggunakan kode berikut.
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$;
Buat fungsi pembungkus
Buat fungsifopen,put_line, dan fclose pembungkus.
fopen
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$;
fclose
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$;
Uji fungsi pengaturan dan pembungkus Anda
Gunakan blok kode anonim berikut untuk menguji pengaturan Anda.
Uji mode tulis
Kode berikut menulis file bernama s3inttest dalam bucket S3.
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; $$
Uji mode append
Kode berikut menambahkan baris ke s3inttest file yang dibuat dalam tes sebelumnya.
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; $$
Pemberitahuan Amazon SNS
Secara opsional, Anda dapat mengatur CloudWatch pemantauan Amazon dan notifikasi Amazon SNS di bucket S3. Untuk informasi selengkapnya, lihat Memantau Amazon S3 dan Menyiapkan Pemberitahuan Amazon SNS.