United CodesのDimitri Gielisさんが、Data Pump APIを使って新しいOracle APEX Application Developmentのサービスにダンプ・ファイルのインポートを行う記事を書いていました。
ワークスペースやAPEXのアプリケーションについては、手間ではありますが、アプリケーションごとにOracle APEXのアプリケーション・ビルダーよりエクスポート/インポートもできます。なので、Autonomous DatabaseからDataPump APIを使ってエクスポートを行って、そのダンプ・ファイルを別のAutonomous Databaseにインポートする手順を確認してみました。
ダンプ・ファイルの受け渡しにはオブジェクト・ストレージを使います。
オブジェクト・ストレージの準備については、以前にまとめた手順があるのですが、もう古い記事になってしまったので、スクリーション・ショットなども含めてやり直してみました。
コンパートメントの作成
すでに作成済みのコンパートメントを使う場合は、この手順は省略できます。また、この通りにコンパートメントを作成しなくても、ポリシーを定義するときに指定するコンパートメントを変更することで手順を進めることができます。
ルート・コンパートメントの直下にDUMPFILESという名前のコンパートメントを作成します。
OCIのコンソールにあるハンバーガー・アイコンをクリックしてメニューを表示させ、ガバナンスと管理に含まれるアイデンティティより、コンパートメントを呼び出します。
グループの作成
ユーザーの作成
ポリシーの作成
Allow group DumpfileManagers to read buckets in compartment DUMPFILES
Allow group DumpfileManagers to manage objects in compartment DUMPFILES
バケットの作成
スキーマのエクスポート
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR');
ファイルがあるかないかは、今まで実施してきた作業に依存します。ですので、結果がどうであれ、特に気にする必要はありません。エクスポートを実施する際に、同じファイル名を指定しないように気をつけてください。
Data Pump APIのマニュアルにある例を参照して、エクスポート処理を実行します。DBMS_DATAPUMP.OPENのjob_name、ADD_FILEのfilename、METADATA_FILTERのvalueといった引数は、それぞれの環境に合わせて必ず変更します。
DECLARE ind NUMBER; -- Loop index h1 NUMBER; -- Data Pump job handle percent_done NUMBER; -- Percentage of job complete job_state VARCHAR2(30); -- To keep track of job state le ku$_LogEntry; -- For WIP and error messages js ku$_JobStatus; -- The job status from get_status jd ku$_JobDesc; -- The job description from get_status sts ku$_Status; -- The status object returned by get_status BEGIN -- Create a (user-named) Data Pump job to do a schema export. h1 := DBMS_DATAPUMP.OPEN( operation => 'EXPORT', job_mode => 'SCHEMA', remote_link => NULL, job_name => 'EXP_APPDEV', version => 'LATEST' ); -- Specify a single dump file for the job (using the handle just returned) -- and a directory object, which must already be defined and accessible -- to the user running this procedure. DBMS_DATAPUMP.ADD_FILE( handle => h1, filename => 'apexdev1.dmp', directory => 'DATA_PUMP_DIR' ); -- A metadata filter is used to specify the schema that will be exported. DBMS_DATAPUMP.METADATA_FILTER( handle => h1, name => 'SCHEMA_EXPR', value => 'IN (''APEXDEV'')' ); -- Start the job. An exception will be generated if something is not set up -- properly. DBMS_DATAPUMP.START_JOB( handle => h1 ); -- The export job should now be running. In the following loop, the job -- is monitored until it completes. In the meantime, progress information is -- displayed. percent_done := 0; job_state := 'UNDEFINED'; while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop dbms_datapump.get_status(h1, dbms_datapump.ku$_status_job_error + dbms_datapump.ku$_status_job_status + dbms_datapump.ku$_status_wip,-1,job_state,sts); js := sts.job_status; -- If the percentage done changed, display the new value. if js.percent_done != percent_done then dbms_output.put_line('*** Job percent done = ' || to_char(js.percent_done)); percent_done := js.percent_done; end if; -- If any work-in-progress (WIP) or error messages were received for the job, -- display them. if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0) then le := sts.wip; else if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0) then le := sts.error; else le := null; end if; end if; if le is not null then ind := le.FIRST; while ind is not null loop dbms_output.put_line(le(ind).LogText); ind := le.NEXT(ind); end loop; end if; end loop; -- Indicate that the job finished and detach from it. dbms_output.put_line('Job has completed'); dbms_output.put_line('Final job state = ' || job_state); dbms_datapump.detach(h1); END; /
スクリプト出力の一例です。
Starting "ADMIN"."EXP_APPDEV":
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
Processing object type SCHEMA_EXPORT/PASSWORD_HISTORY
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCE
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/IDENTITY_COLUMN
Processing object type SCHEMA_EXPORT/FUNCTION/FUNCTION
Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE
Processing object type SCHEMA_EXPORT/FUNCTION/ALTER_FUNCTION
Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE
Processing object type SCHEMA_EXPORT/VIEW/VIEW
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/TRIGGER
Processing object type SCHEMA_EXPORT/POST_SCHEMA/PROCACT_SCHEMA
*** Job percent done = 97
. . exported "APEXDEV"."CWR_MESSAGES" 16.53 MB 153176 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_STOCKS" 116 KB 501 rows
. . exported "APEXDEV"."QS_TASKS" 48.17 KB 73 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_SAMPLE_DATA" 25.43 KB 309 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_TASKS" 20.05 KB 73 rows
. . exported "APEXDEV"."TASKS" 16.85 KB 73 rows
. . exported "APEXDEV"."PRD_TASKS" 14.17 KB 73 rows
. . exported "APEXDEV"."PAC_TASKS" 14.13 KB 73 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_POPULATION" 12.68 KB 51 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_STATS" 10.88 KB 22 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_ORDERS" 9.953 KB 20 rows
. . exported "APEXDEV"."EMP" 10.06 KB 14 rows
. . exported "APEXDEV"."EMP2" 9.828 KB 14 rows
. . exported "APEXDEV"."EMP_LOCAL" 9.835 KB 14 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_BBALL" 9.210 KB 10 rows
. . exported "APEXDEV"."CWR_XLIFF_FILES" 53.81 KB 3 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_GRADES" 8.820 KB 15 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_PROJECTS" 8.656 KB 14 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_EMP" 8.789 KB 14 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_PRODUCTS" 8.554 KB 5 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_SAMPLES" 8.398 KB 100 rows
. . exported "APEXDEV"."CWR_ORDERS" 7.921 KB 4 rows
. . exported "APEXDEV"."WR_ORDERS" 7.898 KB 4 rows
. . exported "APEXDEV"."EBA_DEMO_CHART_SAMPLE_NAMES" 7.765 KB 5 rows
. . exported "APEXDEV"."CWR_MENUS_TL" 6.640 KB 12 rows
. . exported "APEXDEV"."WR_MENUS_TL" 6.632 KB 12 rows
. . exported "APEXDEV"."TST_EMPLOYEES" 6.578 KB 30 rows
. . exported "APEXDEV"."CWR_MENUS" 6.414 KB 3 rows
. . exported "APEXDEV"."WR_MENUS" 6.414 KB 3 rows
. . exported "APEXDEV"."REMEMP" 6.460 KB 3 rows
. . exported "APEXDEV"."PAC_EMPLOYEES" 6.281 KB 12 rows
. . exported "APEXDEV"."PRD_EMPLOYEES" 6.281 KB 12 rows
. . exported "APEXDEV"."PAC_PROJECTS" 6.101 KB 15 rows
. . exported "APEXDEV"."PRD_PROJECTS" 6.101 KB 15 rows
. . exported "APEXDEV"."DEPT" 6.031 KB 4 rows
*** Job percent done = 99
. . exported "APEXDEV"."EBA_DEMO_CHART_DEPT" 6.046 KB 4 rows
ORA-39173: Encrypted data has been stored unencrypted in dump file set.
Master table "ADMIN"."EXP_APPDEV" successfully loaded/unloaded
*** Job percent done = 100
******************************************************************************
Dump file set for ADMIN.EXP_APPDEV is:
/u03/dbfs/AEC9AD8F7E8D9C5AE0532010000A7CA7/data/dpdump/apexdev1.dmp
Job "ADMIN"."EXP_APPDEV" successfully completed at Tue Jan 26 09:27:07 2021
elapsed 0 00:01:08
Job has completed
Final job state = COMPLETED
PL/SQL procedure successfully completed.
Elapsed: 00:01:18.397
スクリプト出力より、エクスポート・ダンプが以下に出力されていることが確認できます。これも今までの作業が違うため、それぞれ異なった値になります。
/u03/dbfs/AEC9AD8F7E8D9C5AE0532010000A7CA7/data/dpdump/apexdev1.dmp
ダンプ・ファイルのオブジェクト・ストレージのへの配置
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR');
BEGIN DBMS_CLOUD.CREATE_CREDENTIAL( credential_name => 'EXPIMP_CRED', username => 'dumpfile_manager', password => 'dumpfile_managerの認証トークン' ); END; /
続いて、DBMS_CLOUD.PUT_OBJECTプロシージャを呼び出し、DATA_PUMP_DIR以下に存在するダンプ・ファイルを作成済みのオブジェクト・ストレージのバケットにコピーします。object_uriはバケットを作成したときに確認したURIから、file_nameはDATA_PUMP_DIRにファイル一覧から決めます。ダンプ・ファイルが複数の場合は、複数回実行します。
BEGIN DBMS_CLOUD.PUT_OBJECT(credential_name => 'EXPIMP_CRED', object_uri => 'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/nr8354yuxaxx/b/Tokyo/o/apexdev1.dmp', directory_name => 'DATA_PUMP_DIR', file_name => 'apexdev1.dmp'); END;
プロシージャの実行が正常に終了したら、オブジェクト・ストレージの画面よりファイルが存在しているか確認してください。
ダンプ・ファイルがオブジェクト・ストレージに存在していれば、エクスポートの作業は完了です。
オブジェクト・ストレージからのダンプ・ファイルの取得
インポートを行うインスタンスのSQL Developer Webに管理者ユーザーADMINでサインインします。
最初にディレクトリDATA_PUMP_DIRの内容を確認します。
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR');
次にエクスポートを実施したインスタンスで実行したのと同様に、DBMS_CLOUD.CREATE_CREDENTIALプロシージャを呼び出し、オブジェクト・ストレージのアクセスに使用するクリデンシャルを登録します。
BEGIN DBMS_CLOUD.CREATE_CREDENTIAL( credential_name => 'EXPIMP_CRED', username => 'dumpfile_manager', password => 'dumpfile_managerの認証トークン' ); END; /
続いて、DBMS_CLOUD.GET_OBJECTプロシージャを呼び出し、オブジェクト・ストレージ上のダンプ・ファイルをDATA_PUMP_DIR以下に配置します。
begin DBMS_CLOUD.GET_OBJECT( credential_name => 'EXPIMP_CRED', object_uri => 'https://objectstorage.ap-tokyo-1.oraclecloud.com/n/nr8354yuxaxx/b/Tokyo/o/apexdev1.dmp', directory_name => 'DATA_PUMP_DIR'); end;
プロシージャが成功したら、ディレクトリDATA_PUMP_DIR以下のファイル一覧を確認します。
SELECT * FROM DBMS_CLOUD.LIST_FILES('DATA_PUMP_DIR');
ダンプ・ファイルが配置されていることを確認し、Data Pump APIを使ったインポート処理を実行します。実行するスクリプトはData Pump APIのマニュアルに記載されている例を元にしています。
DBMS_DATAPUMP.OPENのjob_name、DBMS_DATAPUMP.ADD_FILEのfilename、DBMS_DATAPUMP.METADATA_REMAPなどは環境に応じて必ず変更が発生するはずです。
DECLARE ind NUMBER; -- Loop index h1 NUMBER; -- Data Pump job handle percent_done NUMBER; -- Percentage of job complete job_state VARCHAR2(30); -- To keep track of job state le ku$_LogEntry; -- For WIP and error messages js ku$_JobStatus; -- The job status from get_status jd ku$_JobDesc; -- The job description from get_status sts ku$_Status; -- The status object returned by get_status BEGIN -- Create a (user-named) Data Pump job to do a "full" import (everything -- in the dump file without filtering). h1 := DBMS_DATAPUMP.OPEN( operation => 'IMPORT', job_mode => 'FULL', remote_link => NULL, job_name => 'IMP_APEXDEV' ); -- Specify the single dump file for the job (using the handle just returned) -- and directory object, which must already be defined and accessible -- to the user running this procedure. This is the dump file created by -- the export operation in the first example. DBMS_DATAPUMP.ADD_FILE( handle => h1, filename => 'apexdev1.dmp', directory => 'DATA_PUMP_DIR' ); -- A metadata remap will map all schema objects from HR to BLAKE. DBMS_DATAPUMP.METADATA_REMAP( handle => h1, name => 'REMAP_SCHEMA', old_value => 'APEXDEV', value => 'APEXDEV2' ); -- If a table already exists in the destination schema, skip it (leave -- the preexisting table alone). This is the default, but it does not hurt -- to specify it explicitly. DBMS_DATAPUMP.SET_PARAMETER( handle => h1, name => 'TABLE_EXISTS_ACTION', value => 'SKIP' ); -- Start the job. An exception is returned if something is not set up properly. DBMS_DATAPUMP.START_JOB(h1); -- The import job should now be running. In the following loop, the job is -- monitored until it completes. In the meantime, progress information is -- displayed. Note: this is identical to the export example. percent_done := 0; job_state := 'UNDEFINED'; while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop dbms_datapump.get_status(h1, dbms_datapump.ku$_status_job_error + dbms_datapump.ku$_status_job_status + dbms_datapump.ku$_status_wip,-1,job_state,sts); js := sts.job_status; -- If the percentage done changed, display the new value. if js.percent_done != percent_done then dbms_output.put_line('*** Job percent done = ' || to_char(js.percent_done)); percent_done := js.percent_done; end if; -- If any work-in-progress (WIP) or Error messages were received for the job, -- display them. if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0) then le := sts.wip; else if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0) then le := sts.error; else le := null; end if; end if; if le is not null then ind := le.FIRST; while ind is not null loop dbms_output.put_line(le(ind).LogText); ind := le.NEXT(ind); end loop; end if; end loop; -- Indicate that the job finished and gracefully detach from it. dbms_output.put_line('Job has completed'); dbms_output.put_line('Final job state = ' || job_state); dbms_datapump.detach(h1); END; /
スクリプト出力に表示された実行結果の一例です。
Master table "ADMIN"."IMP_APEXDEV" successfully loaded/unloaded
Starting "ADMIN"."IMP_APEXDEV":
Processing object type SCHEMA_EXPORT/USER
Processing object type SCHEMA_EXPORT/SYSTEM_GRANT
Processing object type SCHEMA_EXPORT/DEFAULT_ROLE
Processing object type SCHEMA_EXPORT/TABLESPACE_QUOTA
Processing object type SCHEMA_EXPORT/PASSWORD_HISTORY
Processing object type SCHEMA_EXPORT/PRE_SCHEMA/PROCACT_SCHEMA
Processing object type SCHEMA_EXPORT/SEQUENCE/SEQUENCE
Processing object type SCHEMA_EXPORT/TABLE/TABLE
Processing object type SCHEMA_EXPORT/TABLE/TABLE_DATA
. . imported "APEXDEV2"."CWR_MENUS" 6.414 KB 3 rows
. . imported "APEXDEV2"."EMP_LOCAL" 9.835 KB 14 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_BBALL" 9.210 KB 10 rows
*** Job percent done = 99
. . imported "APEXDEV2"."CWR_MESSAGES" 16.53 MB 153176 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_TASKS" 20.05 KB 73 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_POPULATION" 12.68 KB 51 rows
. . imported "APEXDEV2"."PRD_EMPLOYEES" 6.281 KB 12 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_PROJECTS" 8.656 KB 14 rows
. . imported "APEXDEV2"."CWR_ORDERS" 7.921 KB 4 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_SAMPLE_DATA" 25.43 KB 309 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_STATS" 10.88 KB 22 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_STOCKS" 116 KB 501 rows
. . imported "APEXDEV2"."WR_MENUS_TL" 6.632 KB 12 rows
. . imported "APEXDEV2"."CWR_XLIFF_FILES" 53.81 KB 3 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_SAMPLES" 8.398 KB 100 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_EMP" 8.789 KB 14 rows
. . imported "APEXDEV2"."PAC_PROJECTS" 6.101 KB 15 rows
. . imported "APEXDEV2"."PRD_PROJECTS" 6.101 KB 15 rows
. . imported "APEXDEV2"."QS_TASKS" 48.17 KB 73 rows
. . imported "APEXDEV2"."WR_MENUS" 6.414 KB 3 rows
. . imported "APEXDEV2"."DEPT" 6.031 KB 4 rows
. . imported "APEXDEV2"."EMP" 10.06 KB 14 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_PRODUCTS" 8.554 KB 5 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_DEPT" 6.046 KB 4 rows
. . imported "APEXDEV2"."PAC_TASKS" 14.13 KB 73 rows
. . imported "APEXDEV2"."PRD_TASKS" 14.17 KB 73 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_ORDERS" 9.953 KB 20 rows
. . imported "APEXDEV2"."TST_EMPLOYEES" 6.578 KB 30 rows
. . imported "APEXDEV2"."REMEMP" 6.460 KB 3 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_GRADES" 8.820 KB 15 rows
. . imported "APEXDEV2"."WR_ORDERS" 7.898 KB 4 rows
. . imported "APEXDEV2"."TASKS" 16.85 KB 73 rows
. . imported "APEXDEV2"."PAC_EMPLOYEES" 6.281 KB 12 rows
. . imported "APEXDEV2"."CWR_MENUS_TL" 6.640 KB 12 rows
. . imported "APEXDEV2"."EMP2" 9.828 KB 14 rows
. . imported "APEXDEV2"."EBA_DEMO_CHART_SAMPLE_NAMES" 7.765 KB 5 rows
Processing object type SCHEMA_EXPORT/TABLE/IDENTITY_COLUMN
Processing object type SCHEMA_EXPORT/FUNCTION/FUNCTION
Processing object type SCHEMA_EXPORT/PROCEDURE/PROCEDURE
Processing object type SCHEMA_EXPORT/FUNCTION/ALTER_FUNCTION
Processing object type SCHEMA_EXPORT/PROCEDURE/ALTER_PROCEDURE
Processing object type SCHEMA_EXPORT/VIEW/VIEW
Processing object type SCHEMA_EXPORT/TABLE/INDEX/INDEX
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/INDEX/STATISTICS/INDEX_STATISTICS
Processing object type SCHEMA_EXPORT/TABLE/CONSTRAINT/REF_CONSTRAINT
Processing object type SCHEMA_EXPORT/TABLE/TRIGGER
Processing object type SCHEMA_EXPORT/TABLE/STATISTICS/TABLE_STATISTICS
Processing object type SCHEMA_EXPORT/STATISTICS/MARKER
Processing object type SCHEMA_EXPORT/POST_SCHEMA/PROCACT_SCHEMA
Job "ADMIN"."IMP_APEXDEV" successfully completed at Tue Jan 26 10:18:26 2021
elapsed 0 00:00:47
Job has completed
Final job state = COMPLETED
PL/SQL procedure successfully completed.
Elapsed: 00:00:57.454
インポートされた表などは、SQL Developer Webを使用して確認することができます。
以上で、Data Pump APIを使ったエクスポートとインポート作業の紹介は完了です。Oracle APEXを使ったアプリケーション開発の一助になれば幸いです。
追記
DATA_PUMP_DIR以下のファイルを削除するには、DBMS_CLOUD.DELETE_FILEプロシージャを使用します。
begin dbms_cloud.delete_file( directory_name => 'DATA_PUMP_DIR', file_name => 'apexdev1.dmp'); end;
完