본문 바로가기

챱챱

[Ora2Pg] Ora2Pg 설치 및 실행하기

안녕하세요. 데이터를 이관하다보면 Oracle -> PostgreSQL로 진행하게 되는데요. 이럴때, 사용할 수 있는 Ora2Pg에 설치 방법과 실행 방법에 대해서 정리해보려고 합니다. 해당 내용은 Rocky Linux 9.4 버전으로 진행되고 있는 점을 참고해주시면 좋을 것 같습니다🤗🤗


1. 설치하기

Ora2Pg 21.16.0 버전으로 진행합니다. 해당 링크에 들어가서 맞는 버전으로 `base, sdk` 파일 다운받으면 됩니다.
https://www.oracle.com/database/technologies/instant-client/linux-x86-64-downloads.html

 

Instant Client for Linux x86-64 (64-bit)

Base - one of these packages is required Tools - optional packages Development and Runtime - optional packages

www.oracle.com

 

1-1. 압축풀기

sudo mkdir -p /opt/oracle/instantclient
sudo unzip instantclient-basic-linux.x64-21.16.0.0dbru.zip -d /opt/oracle/instantclient
sudo unzip instantclient-sdk-linux.x64-21.16.0.0dbru.zip -d /opt/oracle/instantclient
  • 다운받은 파일들의 압축을 풀어서 실행을 준비합니다.

1-2. 환경변수 설정하기

echo "export ORACLE_HOME=/opt/oracle/instantclient/instantclient_21_16" >> ~/.bashrc
echo "export LD_LIBRARY_PATH=\$ORACLE_HOME" >> ~/.bashrc
echo "export PATH=\$ORACLE_HOME:\$PATH" >> ~/.bashrc
echo "export C_INCLUDE_PATH=\$ORACLE_HOME/sdk/include" >> ~/.bashrc
echo "export OCI_LIB_DIR=\$ORACLE_HOME" >> ~/.bashrc
echo "export OCI_INC_DIR=\$ORACLE_HOME/sdk/include" >> ~/.bashrc

source ~/.bashrc

 

1-3. perl-DBD-Oracle 설치하기

sudo dnf install -y perl-CPAN perl-devel gcc

perl -MCPAN -e shell

install DBD::Oracle

exit
  • perl -MCPAN -e shell 명령어를 통하여 shell에 들어가서 설치를 진행합니다.
  • perl-DBD-Oracle은 dnf로 설치가 안됨으로 따로 설치를 진행하는 것이 좋습니다.
perl -MDBD::Oracle -e 'print $DBD::Oracle::VERSION, "\n";'
  • 명령어를 통해서 버전이 나온다면 잘 설치된 것입니다.

1-4. 필요 패키지 설치하기

1-4-1. Perl 패키지 설치하기

sudo dnf install -y perl make gcc perl-DBI perl-DBD-Pg perl-JSON perl-XML-LibXML unzip
  • dnf 명령어를 이용하여서 perl에 관련된 패키지들을 설치합니다.

1-4-2. Ora2Pg 설치하기

wget https://github.com/darold/ora2pg/archive/refs/tags/v23.0.tar.gz -O ora2pg.tar.gz
tar -xzf ora2pg.tar.gz
cd ora2pg-23.0

# Perl 모듈 설치
perl Makefile.PL

# Ora2Pg 빌드 및 설치
make
sudo make install

# 설치 확인
ora2pg --version
  • perl 모듈을 설치한 후에 Ora2Pg를 설치할 수 있습니다.
  • 설치가 완료되었다면, 버전 체크를 통해서 설치가 완료되었는지 확인합니다.

1-4-3. PostgreSQL 설치하기

sudo dnf install postgresql
  • PostgreSQL도 사용됨으로 dnf를 이용하여 같이 설치해줍니다.

2. Ora2Pg 프로젝트 구성

2-1. Ora2Pg 프로젝트 위치 설정

ora2pg --project_base [원하는 경로] --init_project [원하는 프로젝트 이름]
  • ora2pg 명령어를 사용하여 프로젝트를 원하는 경로와 원하는 이름으로 시작합니다.

2-2. Ora2Pg 설정

2-2-1. Ora2Pg conf 파일 복사

cp /etc/ora2pg/ora2pg.conf.dist [위에서 지정한 경로]/[프로젝트 이름]/config/ora2pg.conf
  • 설치시에 생성된 conf 파일이 아닌 사용자가 지정한 conf 를 사용하기 위해서 원본을 가지고 있고 cp 명령어를 통해서 복사해줍니다.

2-2-2. Ora2Pg conf 설정

ora2pg.conf
0.06MB

# COPY를 이용해서 데이터를 복사
USE_COPY        YES

# Oracle 설치 환경 변수 지정
ORACLE_HOME     /opt/oracle/instantclient/instantclient_21_16

# Oracle host, port, service name 혹은 SID 지정
ORACLE_DSN dbi:[HOST];port=[PORT];service_name=[SERVICE_NAME];

# Oracle User, Password
ORACLE_USER    [ORACLE_USER]
ORACLE_PWD     [ORACLE_PWD]

# Oracle Schema, 지정안하면 다 가져옴
SCHEMA         [SCHEMA]

# PG dbname, host, port 지정
PG_DSN         dbi:Pg:dbname=[DBNAME];host=[HOST];port=[PORT]

# PG User, Password
PG_USER        [PG_USER]
PG_PWD         [PG_PWD]

# 전체 가져오기
FULL_EXPORT    1

# 전체 내용 가져오기(TABLE, QUERY 등)
TYPE           FULL

# 테이블을 지정
ALLOW          [TABLE_NAME]

# Debug를 같이 보고 싶으면 1로 변경
DEBUG           0

# Schema 사용
EXPORT_SCHEMA   1
  • 첨부한 파일에는 전체적인 conf 파일의 내용들이 다 들어가있습니다.
  • 현재 따로 코드로 나타낸 부분들이 기존의 내용에서 변경을 진행한 부분들입니다.
  • 설정에 맞게 Oracle, PostgreSQL Host, Port, Schema, ID, PW, 테이블 지정들을 고려해서 작성해야합니다.
  • TYPE 내용은 밑의 링크를 통해서 확인할 수 있습니다.

3. PostgreSQL 권한 설정

# 유저 생성하기 - 슈퍼 유저 혹은 SYS에 들어가서 실행
CREATE USER [USER] WITH PASSWORD 'your_password';

# 데이터베이스 생성 및 소유자 지정
CREATE DATABASE [DATABASE] OWNER [USER];

# 특정 데이터베이스에 대한 모든 권한 부여
GRANT ALL PRIVILEGES ON DATABASE [DATABASE] TO [USER];

# 특정 스키마 대한 권한 부여 - database에 들어가서 실행
\c [DATABASE]
CREATE SCHEMA datamart AUTHORIZATION [USER];
GRANT ALL ON SCHEMA datamart TO [USER];
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO [USER];
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO [USER];
SET search_path TO [USER],public;
  • ora2pg.conf에서 설정한 Schema를 기준으로 PostgreSQL에 Schema 이름과 동일한 User와 Schema가있어야합니다.
  • PostgreSQL에서 유저를 생성하고 해당 유저에게 Schema에 대한 권한을 부여합니다.

4. Oracle 권한 설정

CREATE USER [USER] IDENTIFIED BY [PWD];

GRANT CONNECT TO [USER];
GRANT RESOURCE TO [USER];

GRANT SELECT ANY TABLE TO [USER]; 
GRANT SELECT ANY DICTIONARY TO [USER];

GRANT SELECT ON ALL_TABLES TO [USER];
GRANT SELECT ON ALL_INDEXES TO [USER];
GRANT SELECT ON ALL_CONSTRAINTS TO [USER];
GRANT SELECT ON ALL_SEQUENCES TO [USER];
GRANT SELECT ON ALL_TAB_COLUMNS TO [USER];
  • Oralce에서도 마찬가지로 유저를 생성하고 유저에게 ora2pg를 하기 위한 권한을 설정해줍니다.
  • PostgreSQL과 Oracle에서 생성한 유저 모두 ora2pg.conf에 포함되어있어야합니다.

5. Ora2Pg 연결 확인하기

ora2pg -t SHOW_VERSION -c config/ora2pg.conf
  • 오류가 안나고 버전이 나오면 잘 연결된 것입니다.
ora2pg -t SHOW_REPORT -c config/ora2pg.conf --estimate_cost --dump_as_html > migration_report.html
  • migration_report.html 이 생기게 되는데, 크롬으로 열어보면 해당 Schema를 옮기는데 어느 정도의 난이도인지를 확인할 수 있습니다.

6. Export 하기(Oracle -> Ora2Pg)

#!/bin/sh
#-------------------------------------------------------------------------------
#
# Generated by Ora2Pg, the Oracle database Schema converter, version 23.0
#
#-------------------------------------------------------------------------------
EXPORT_TYPE="SEQUENCE TABLE PACKAGE VIEW GRANT TRIGGER FUNCTION PROCEDURE TABLESPACE PARTITION TYPE MVIEW DBLINK SYNONYM DIRECTORY"
SOURCE_TYPE="PACKAGE VIEW TRIGGER FUNCTION PROCEDURE PARTITION TYPE MVIEW"
namespace="."
unit_cost=5

script_start_time=$(date +%s)
echo "Script started at: $(date)"

ora2pg -t SHOW_TABLE -c $namespace/config/ora2pg.conf > $namespace/reports/tables.txt
ora2pg -t SHOW_COLUMN -c $namespace/config/ora2pg.conf > $namespace/reports/columns.txt
ora2pg -t SHOW_REPORT -c $namespace/config/ora2pg.conf --dump_as_html --cost_unit_value  $unit_cost --estimate_cost > $namespace/reports/report.html

for etype in $(echo $EXPORT_TYPE | tr " " "\n")
do
        ltype=`echo $etype | tr '[:upper:]' '[:lower:]'`
        ltype=`echo $ltype | sed 's/y$/ie/'`
        echo "Running: ora2pg -p -t $etype -o $ltype.sql -b $namespace/schema/${ltype}s -c $namespace/config/ora2pg.conf"
        ora2pg -p -t $etype -o $ltype.sql -b $namespace/schema/${ltype}s -c $namespace/config/ora2pg.conf
	ret=`grep "Nothing found" $namespace/schema/${ltype}s/$ltype.sql 2> /dev/null`
	if [ ! -z "$ret" ]; then
		rm $namespace/schema/${ltype}s/$ltype.sql
	fi
done

for etype in $(echo $SOURCE_TYPE | tr " " "\n")
do
        ltype=`echo $etype | tr '[:upper:]' '[:lower:]'`
        ltype=`echo $ltype | sed 's/y$/ie/'`
        echo "Running: ora2pg -t $etype -o $ltype.sql -b $namespace/sources/${ltype}s -c $namespace/config/ora2pg.conf"
        ora2pg -t $etype -o $ltype.sql -b $namespace/sources/${ltype}s -c $namespace/config/ora2pg.conf
	ret=`grep "Nothing found" $namespace/sources/${ltype}s/$ltype.sql 2> /dev/null`
	if [ ! -z "$ret" ]; then
		rm $namespace/sources/${ltype}s/$ltype.sql
	fi
done

echo
echo
echo "To extract data use the following command:"
echo
echo "ora2pg -t COPY -o data.sql -b $namespace/data -c $namespace/config/ora2pg.conf"
echo

script_end_time=$(date +%s)
script_elapsed_time=$(($script_end_time - $script_start_time))

echo "Script ended at: $(date)"
echo "Total script execution time: $script_elapsed_time seconds"

exit 0
./export_schema.sh
  • project안에 생성된 `export_schema.sh` 파일을 실행해서 테이블의 스키마를 받아올 수 있습니다.
  • 현재 코드안에 실행 시간을 확인할 수 있도록 시간을 찍을 수 있게 추가해놓았습니다.
  • Export가 완료되면, schema 폴더 -> tables 폴더 -> table.sql 이 생성된 것을 확인할 수 있습니다.

7. Import 하기(Ora2Pg -> PostgreSQL)

#!/bin/sh
#-------------------------------------------------------------------------------
#
# Script used to load exported sql files into PostgreSQL in practical manner
# allowing you to chain and automatically import schema and data.
#
# Generated by Ora2Pg, the Oracle database Schema converter, version 23.0
#
#-------------------------------------------------------------------------------

EXPORT_TYPE="TYPE SEQUENCE TABLE PACKAGE VIEW GRANT TRIGGER FUNCTION PROCEDURE TABLESPACE PARTITION MVIEW DBLINK SYNONYM DIRECTORY"
AUTORUN=0
NAMESPACE=.
NO_CONSTRAINTS=0
IMPORT_INDEXES_AFTER=0
DEBUG=0
IMPORT_SCHEMA=0
IMPORT_DATA=0
IMPORT_CONSTRAINTS=0
NO_DBCHECK=0

script_start_time=$(date +%s)
echo "Script started at: $(date)"

# Message functions
die() {
    echo "ERROR: $1" 1>&2
    exit 1
}

usage() {
    echo "usage: `basename $0` [options]"
    echo ""
    echo "Script used to load exported sql files into PostgreSQL in practical manner"
    echo "allowing you to chain and automatically import schema and data."
    echo ""
    echo "options:"
    echo "    -a             import data only"
    echo "    -b filename    SQL script to execute just after table creation to fix database schema"
    echo "    -d dbname      database name for import"
    echo "    -D             enable debug mode, will only show what will be done"
    echo "    -e encoding    database encoding to use at creation (default: UTF8)"
    echo "    -f             force no check of user and database existing and do not try to create them"
    echo "    -h hostname    hostname of the PostgreSQL server (default: unix socket)"
    echo "    -i             only load indexes, constraints and triggers"
    echo "    -I             do not try to load indexes, constraints and triggers"
    echo "    -j cores       number of connection to use to import data or indexes into PostgreSQL"
    echo "    -n schema      comma separated list of schema to create"
    echo "    -o username    owner of the database to create"
    echo "    -p port        listening port of the PostgreSQL server (default: 5432)"
    echo "    -P cores       number of tables to process at same time for data import"
    echo "    -s             import schema only, do not try to import data"
    echo "    -t export      comma separated list of export type to import (same as ora2pg)"
    echo "    -U username    username to connect to PostgreSQL (default: peer username)"
    echo "    -x             import indexes and constraints after data"
    echo "    -y             reply Yes to all questions for automatic import"
    echo
    echo "    -?             print help"
    echo
    exit $1
}

# Function to emulate Perl prompt function
confirm () {

    msg=$1
    if [ "$AUTORUN" != "0" ]; then
	true
    else
	    if [ -z "$msg" ]; then
		msg="Are you sure? [y/N/q]"
	    fi
	    # call with a prompt string or use a default
	    read -r -p "${msg} [y/N/q] " response
	    case $response in
		[yY][eE][sS]|[yY])
		    true
		    ;;
		[qQ][uU][iI][tT]|[qQ])
		    exit
		    ;;
		*)
		    false
		    ;;
	    esac
    fi
}

# Function used to import constraints and indexes
import_constraints () {
	if [ -r "$NAMESPACE/schema/tables/INDEXES_table.sql" ]; then
		if confirm "Would you like to import indexes from $NAMESPACE/schema/tables/INDEXES_table.sql?" ; then
			if [ -z "$IMPORT_JOBS" ]; then
				echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/INDEXES_table.sql"
				if [ $DEBUG -eq 0 ]; then
					psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/INDEXES_table.sql
					if [ $? -ne 0 ]; then
						die "can not import indexes."
					fi
				fi
			else
				echo "Running: ora2pg -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/INDEXES_table.sql"
				if [ $DEBUG -eq 0 ]; then
					ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/INDEXES_table.sql
					if [ $? -ne 0 ]; then
						die "can not import indexes."
					fi
				fi
			fi
		fi
	fi

	if [ -r "$NAMESPACE/schema/tables/CONSTRAINTS_table.sql" ]; then
		if confirm "Would you like to import constraints from $NAMESPACE/schema/tables/CONSTRAINTS_table.sql?" ; then
			if [ -z "$IMPORT_JOBS" ]; then
				echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/CONSTRAINTS_table.sql"
				if [ $DEBUG -eq 0 ]; then
					psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/CONSTRAINTS_table.sql
					if [ $? -ne 0 ]; then
						die "can not import constraints."
					fi
				fi
			else
				echo "Running: ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/CONSTRAINTS_table.sql"
				if [ $DEBUG -eq 0 ]; then
					ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/CONSTRAINTS_table.sql
					if [ $? -ne 0 ]; then
						die "can not import constraints."
					fi
				fi
			fi
		fi
	fi

	if [ -r "$NAMESPACE/schema/tables/FKEYS_table.sql" ]; then
		if confirm "Would you like to import foreign keys from $NAMESPACE/schema/tables/FKEYS_table.sql?" ; then
			if [ -z "$IMPORT_JOBS" ]; then
				echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/FKEYS_table.sql"
				if [ $DEBUG -eq 0 ]; then
					psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/tables/FKEYS_table.sql
					if [ $? -ne 0 ]; then
						die "can not import foreign keys."
					fi
				fi
			else
				echo "Running: ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/FKEYS_table.sql"
				if [ $DEBUG -eq 0 ]; then
					ora2pg$IMPORT_JOBS -c config/ora2pg.conf -t LOAD -i $NAMESPACE/schema/tables/FKEYS_table.sql
					if [ $? -ne 0 ]; then
						die "can not import foreign keys."
					fi
				fi
			fi
		fi
	fi

	if [ -r "$NAMESPACE/schema/triggers/trigger.sql" ]; then
		if confirm "Would you like to import TRIGGER from $NAMESPACE/schema/triggers/trigger.sql?" ; then
			echo "Running: psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/triggers/trigger.sql"
			if [ $DEBUG -eq 0 ]; then
				psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/triggers/trigger.sql
				if [ $? -ne 0 ]; then
					die "an error occurs when importing file $NAMESPACE/schema/triggers/trigger.sql."
				fi
			fi
		fi
	fi
}

# Command line options
while getopts "b:d:e:h:j:l:n:o:p:P:t:U:aDfiIsyx?"  opt; do
    case "$opt" in
	a) IMPORT_DATA=1;;
	b) SQL_POST_SCRIPT=$OPTARG;;
        d) DB_NAME=$OPTARG;;
        D) DEBUG=1;;
        e) DB_ENCODING=" -E $OPTARG";;
	f) NO_DBCHECK=1;;
        h) DB_HOST=" -h $OPTARG";;
        i) IMPORT_CONSTRAINTS=1;;
        I) NO_CONSTRAINTS=1;;
        j) IMPORT_JOBS=" -j $OPTARG";;
        n) DB_SCHEMA=$OPTARG;;
        o) DB_OWNER=$OPTARG;;
        p) DB_PORT=" -p $OPTARG";;
        P) PARALLEL_TABLES=" -P $OPTARG";;
        s) IMPORT_SCHEMA=1;;
        t) EXPORT_TYPE=$OPTARG;;
        U) DB_USER=" -U $OPTARG";;
	x) IMPORT_INDEXES_AFTER=1;;
        y) AUTORUN=1;;
        "?") usage 1;;
        *) die "Unknown error while processing options";;
    esac
done

# Check if post tables import SQL script is readable
if [ ! -z "$SQL_POST_SCRIPT" ]; then
	if [ ! -r "$SQL_POST_SCRIPT" ]; then
		die "the SQL script $SQL_POST_SCRIPT is not readable."
	fi
fi

# A database name is mandatory
if [ -z "$DB_NAME" ]; then
	die "you must give a PostgreSQL database name (see -d option)."
fi

# A database owner is mandatory
if [ -z "$DB_OWNER" ]; then
	die "you must give a username to be used as owner of database (see -o option)."
fi

# Check if the project directory is readable
if [ ! -r "$NAMESPACE/schema/tables/table.sql" ]; then
	die "project directory '$NAMESPACE' is not valid or is not readable."
fi

# If constraints and indexes files are present propose to import these objects
if [ $IMPORT_CONSTRAINTS -eq 1 ]; then
	if confirm "Would you like to load indexes, constraints and triggers?" ; then
		import_constraints
	fi
	exit 0
fi

# When a PostgreSQL schema list is provided, create them
if [ $IMPORT_DATA -eq 0 ]; then
	is_superuser='f'
	if [ $NO_DBCHECK  -eq 0 ]; then
		# Create owner user
		user_exists=`psql -d $DB_NAME$DB_HOST$DB_PORT$DB_USER -Atc "select usename from pg_user where usename='$DB_OWNER';" 2>/dev/null`
		is_superuser=`psql -d $DB_NAME$DB_HOST$DB_PORT$DB_USER -Atc "select usesuper from pg_user where usename='$DB_OWNER';" 2>/dev/null`;
		if [ "a$user_exists" = "a" ]; then
			if confirm "Would you like to create the owner of the database $DB_OWNER?" ; then
				echo "Running: createuser$DB_HOST$DB_PORT$DB_USER --no-superuser --no-createrole --no-createdb $DB_OWNER"
				if [ $DEBUG -eq 0 ]; then
					createuser$DB_HOST$DB_PORT$DB_USER --no-superuser --no-createrole --no-createdb $DB_OWNER
					if [ $? -ne 0 ]; then
						die "can not create user $DB_OWNER."
					fi
				fi
			fi
		else
			echo "Database owner $DB_OWNER already exists, skipping creation."
		fi

		# Create database if required
		if [ "a$DB_ENCODING" = "a" ]; then
			DB_ENCODING=" -E UTF8"
		fi
		db_exists=`psql -d $DB_NAME$DB_HOST$DB_PORT$DB_USER -Atc "select datname from pg_database where datname='$DB_NAME';"`
		if [ "a$db_exists" = "a" ]; then
			if confirm "Would you like to create the database $DB_NAME?" ; then
				echo "Running: createdb$DB_HOST$DB_PORT$DB_USER$DB_ENCODING --owner $DB_OWNER $DB_NAME"
				if [ $DEBUG -eq 0 ]; then
					createdb$DB_HOST$DB_PORT$DB_USER$DB_ENCODING --owner $DB_OWNER $DB_NAME
					if [ $? -ne 0 ]; then
						die "can not create database $DB_NAME."
					fi
				fi
			fi
		else
			if confirm "Would you like to drop the database $DB_NAME before recreate it?" ; then
				echo "Running: dropdb$DB_HOST$DB_PORT$DB_USER $DB_NAME"
				if [ $DEBUG -eq 0 ]; then
					dropdb$DB_HOST$DB_PORT$DB_USER $DB_NAME
					if [ $? -ne 0 ]; then
						die "can not drop database $DB_NAME."
					fi
				fi
				echo "Running: createdb$DB_HOST$DB_PORT$DB_USER$DB_ENCODING --owner $DB_OWNER $DB_NAME"
				if [ $DEBUG -eq 0 ]; then
					createdb$DB_HOST$DB_PORT$DB_USER$DB_ENCODING --owner $DB_OWNER $DB_NAME
					if [ $? -ne 0 ]; then
						die "can not create database $DB_NAME."
					fi
				fi
			fi
		fi
	fi

	# When schema list is provided, create them
	if [ "a$DB_SCHEMA" != "a" ]; then
		nspace_list=''
		for enspace in $(echo $DB_SCHEMA | tr "," "\n")
		do
			lnspace=`echo $enspace | tr '[:upper:]' '[:lower:]'`
			if confirm "Would you like to create schema $lnspace in database $DB_NAME?" ; then
				echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -c \"CREATE SCHEMA $lnspace;\""
				if [ $DEBUG -eq 0 ]; then
					psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -c "CREATE SCHEMA $lnspace;"
					if [ $? -ne 0 ]; then
						die "can not create schema $DB_SCHEMA."
					fi
				fi
				nspace_list="$nspace_list$lnspace,"
			fi
		done
		# Change search path of the owner
		if [ "a$nspace_list" != "a" ]; then
			if confirm "Would you like to change search_path of the database owner?" ; then
				echo "Running: psql$DB_HOST$DB_PORT$DB_USER -d $DB_NAME -c \"ALTER ROLE $DB_OWNER SET search_path TO ${nspace_list}public;\""
				if [ $DEBUG -eq 0 ]; then
					psql$DB_HOST$DB_PORT$DB_USER -d $DB_NAME -c "ALTER ROLE $DB_OWNER SET search_path TO ${nspace_list}public;"
					if [ $? -ne 0 ]; then
						die "can not change search_path."
					fi
				fi
			fi
		fi
	fi

	# Then import all files from project directory
	for etype in $(echo $EXPORT_TYPE | tr "," "\n")
	do

		if [ $NO_CONSTRAINTS -eq 1 ] && [ $etype = "TRIGGER" ]; then
			continue
		fi

		if [ $etype = "GRANT" ] || [ $etype = "TABLESPACE" ]; then
			continue
		fi

		ltype=`echo $etype | tr '[:upper:]' '[:lower:]'`
		ltype=`echo $ltype | sed 's/y$/ie/'`
		if [ -r "$NAMESPACE/schema/${ltype}s/$ltype.sql" ]; then
			if confirm "Would you like to import $etype from $NAMESPACE/schema/${ltype}s/$ltype.sql?" ; then
				echo "Running: psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/${ltype}s/$ltype.sql"
				if [ $DEBUG -eq 0 ]; then
					psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/schema/${ltype}s/$ltype.sql
					if [ $? -ne 0 ]; then
						die "an error occurs when importing file $NAMESPACE/schema/${ltype}s/$ltype.sql."
					fi
				fi
			fi
		fi
		if [ ! -z "$SQL_POST_SCRIPT" ] && [ $etype = "TABLE" ]; then
			if confirm "Would you like to execute SQL script $SQL_POST_SCRIPT?" ; then
				echo "Running: psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $SQL_POST_SCRIPT"
				if [ $DEBUG -eq 0 ]; then
					psql --single-transaction $DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $SQL_POST_SCRIPT
					if [ $? -ne 0 ]; then
						die "an error occurs when importing file $SQL_POST_SCRIPT."
					fi
				fi
			fi
		fi
	done

	# If constraints and indexes files are present propose to import these objects
	if [ $NO_CONSTRAINTS -eq 0 ] && [ $IMPORT_INDEXES_AFTER -eq 0 ]; then
		if confirm "Would you like to process indexes and constraints before loading data?" ; then
			IMPORT_INDEXES_AFTER=0
			import_constraints
		else
			IMPORT_INDEXES_AFTER=1
		fi
	fi

	# When the database owner is not superuser use postgres instead
	q_user='postgres'
	if [ "$is_superuser" = "t" ]; then
		q_user=$DB_OWNER
	fi

	# Import objects that need superuser privilege: GRANT and TABLESPACE
	if [ -r "$NAMESPACE/schema/grants/grant.sql" ]; then
		if confirm "Would you like to import GRANT from $NAMESPACE/schema/grants/grant.sql?" ; then
			echo "Running: psql $DB_HOST$DB_PORT -U $q_user -d $DB_NAME -f $NAMESPACE/schema/grants/grant.sql"
			if [ $DEBUG -eq 0 ]; then
				psql $DB_HOST$DB_PORT -U $q_user -d $DB_NAME -f $NAMESPACE/schema/grants/grant.sql
				if [ $? -ne 0 ]; then
					die "an error occurs when importing file $NAMESPACE/schema/grants/grant.sql."
				fi
			fi
		fi
	fi
	if [ -r "$NAMESPACE/schema/tablespaces/tablespace.sql" ]; then
		if confirm "Would you like to import TABLESPACE from $NAMESPACE/schema/tablespaces/tablespace.sql?" ; then
			echo "Running: psql $DB_HOST$DB_PORT -U $q_user -d $DB_NAME -f $NAMESPACE/schema/tablespaces/tablespace.sql"
			if [ $DEBUG -eq 0 ]; then
				psql $DB_HOST$DB_PORT -U $q_user -d $DB_NAME -f $NAMESPACE/schema/tablespaces/tablespace.sql
				if [ $? -ne 0 ]; then
					die "an error occurs when importing file $NAMESPACE/schema/tablespaces/tablespace.sql."
				fi
			fi
		fi
	fi
fi


# Check if we must just import schema or proceed to data import too
if [ $IMPORT_SCHEMA -eq 0 ]; then
	# set the PostgreSQL datasource
	pgdsn_defined=`grep "^PG_DSN" config/ora2pg.conf | sed 's/.*dbi:Pg/dbi:Pg/'`
	if [ "a$pgdsn_defined" = "a" ]; then
		if [ "a$DB_HOST" != "a" ]; then
			pgdsn_defined="dbi:Pg:dbname=$DB_NAME;host=$DB_HOST"
		else
      #default to unix socket
      pgdsn_defined="dbi:Pg:dbname=$DB_NAME;"
    fi
		if [ "a$DB_PORT" != "a" ]; then
			pgdsn_defined="$pgdsn_defined;port=$DB_PORT"
		else
			pgdsn_defined="$pgdsn_defined;port=5432"
		fi
	fi

	# remove command line option from the DSN string
	pgdsn_defined=`echo "$pgdsn_defined" | sed 's/ -. //g'`

	# If data file is present propose to import data
	if [ -r "$NAMESPACE/data/data.sql" ]; then
		if confirm "Would you like to import data from $NAMESPACE/data/data.sql?" ; then
			echo "Running: psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/data/data.sql"
			if [ $DEBUG -eq 0 ]; then
				psql$DB_HOST$DB_PORT -U $DB_OWNER -d $DB_NAME -f $NAMESPACE/data/data.sql
				if [ $? -ne 0 ]; then
					die "an error occurs when importing file $NAMESPACE/data/data.sql."
				fi
			fi
		fi
	else
		# Import data directly from PostgreSQL
		if confirm "Would you like to import data from Oracle database directly into PostgreSQL?" ; then
			echo "Running: ora2pg$IMPORT_JOBS$PARALLEL_TABLES -c config/ora2pg.conf -t COPY --pg_dsn \"$pgdsn_defined\" --pg_user $DB_OWNER"
			if [ $DEBUG -eq 0 ]; then
				ora2pg$IMPORT_JOBS$PARALLEL_TABLES -c config/ora2pg.conf -t COPY --pg_dsn "$pgdsn_defined" --pg_user $DB_OWNER -j 16 -L 50000
				if [ $? -ne 0 ]; then
					die "an error occurs when importing data."
				fi
			fi
		fi
	fi

	if [ $NO_CONSTRAINTS -eq 0 ] && [ $IMPORT_DATA -eq 0 ]; then
		# Import indexes and constraint after data
		if [ $IMPORT_INDEXES_AFTER -eq 1 ]; then
			import_constraints
		fi
	fi
fi

script_end_time=$(date +%s)
script_elapsed_time=$(($script_end_time - $script_start_time))

echo "Script ended at: $(date)"
echo "Total script execution time: $script_elapsed_time seconds"

exit 0
PGPASSWORD='[PG 비밀번호]' ./import_all.sh -h [PG host] \
  -p [PG port] \
  -U [PG user] \
  -o [PG owner] \
  -d [PG database]
  • project안에 생성된 `import_all.sh` 파일을 실행해서 테이블을 생성하고 데이터를 넣을 수 있습니다.
  • 실행하기 위해서는 PostgreSQL의 해당하는 내용들을 적어주어야합니다.
  • host, user, password, user, owner, database
  • 현재 파일에는 안에 실행 시간을 확인할 수 있도록 시간을 찍을 수 있게 추가해놓았습니다
  • -j / -p등 옵션을 추가해서 처리 속도를 높일 수 있습니다.
  • `ora2pg$IMPORT_JOBS$PARALLEL_TABLES -c config/ora2pg.conf -t COPY --pg_dsn "$pgdsn_defined" --pg_user $DB_OWNER -j 16 -L 50000`
  • 파일안에 들어가면 밑의 부분에 COPY 명령어를 통해서 데이터를 넣는 부분이 있습니다. 해당 부분에서는 옵션을 추가해서 사용할 수 있습니다.
  • `-j` : 작업 단위 병렬 처리, 테이블 작업의 대한 병렬 처리, 일반적으로 CPU 코어 수의 50~75%로 설정합니다.
  • `-p` : 테이블 단위 병렬 처리, 테이블당 병렬 처리를 진행할 수 있습니다.
  • `-L` :  한 번에 추출할 데이터의 최대 행(row) 수를 제한, 과부화를 방지합니다.
  • 해당 파일을 실행하면, y or n을 입력해서 진행하는데 directories 부분은 파일의 내용이 없으면 에러가 남으로 n을 눌러서 넘겨줍니다.

 


이렇게 진행해보면, Ora2Pg가 작동되는 것을 실시간으로 볼 수 있습니다. 처음에 설치하는 과정이 어렵지만, 한번 설정을 진행해놓으면 명령어를 통해서 쉽게 데이터를 이관할 수 있는 장점이 있습니다. 가끔 사용자 지정 인덱스들이 이관되지 않는 일도 있으니 주의하시기 바랍니다. 보다 쉽게 데이터를 이관하시기를 바라면, 해당 내용이 여러분의 궁금증에 도움이 되었기를 바랍니다. 다음에도 더 유익한 내용으로 찾아오겠습니다!🤓🤓