StoryCode

Tibero to PostgreSQL

Database 관리/Tibero
반응형

# 참조 : https://cbwstar.tistory.com/110

 

티베로에서 postgresql로 데이타 이관하는 소스 입니다.

파이션으로 만들었습니다.

80만건 되는 데이터를 엑셀로 다운받아서 해볼려고 했는데 엑셀로 80만건 내려받는데 20분이 넘게 걸려서 포기하고

파이쎤으로 만들어 볼까 하고 만들었는데 외상예로 처리 속도가 빨라서 jdbc만 지원하는 모든 데이터 베이스 이관은 이것 하나 응용하면 끝날것 같아서 필요 하신분 있을것 같아서 소스 공개합니다.

80만건 티베로에서 postgresql로 이관시 2분도 안 걸렸습니다.

소스 로직도 간단 합니다. db접속해서 원하는 데이터 쿼리로 가져와서 그냥 sqlalchemy 라이브러리 사용해서 밀어 넣으면 끝입니다.

from sqlalchemy import create_engine
import sqlalchemy.types as sql_types
import jaydebeapi as jp
import pandas as pd
import time

tibero_JDBC_Driver = 'd:\import_trans_erd\python\jdbc\\tibero6-jdbc.jar'
drivers = [tibero_JDBC_Driver]


def postgres_connect(user, password, db, host, port=5432):
    url = 'postgresql://{}:{}@{}:{}/{}'.format(user, password, host, port, db)
    engine = create_engine(url, client_encoding='utf8',
                           executemany_mode='batch')
    return engine


def tibero_connect():
    conn = jp.connect('com.tmax.tibero.jdbc.TbDriver',
                      'jdbc:tibero:thin:@192.168.1.19:9027:naqs', ['id', 'password'], jars=drivers)
    return conn


user = 'id'
password = 'pw'
db = 'naqs'
host = '192.168.1.26'

query = """
    SELECT *
      FROM TABLE
    """

start_time = time.time()
tb_conn = tibero_connect()
df = pd.read_sql_query(query, tb_conn)

pg_engine = postgres_connect(user, password, db, host)
start_time1 = time.time()

print(df.columns)

df.to_sql('table_name_tmp',
          schema='test',
          con=pg_engine,
          if_exists='replace',  # {'fail', 'replace', 'append'), default 'fail'
          chunksize=1000,
          index=False,
          method='multi',
          dtype={
              'LGN_ID': sql_types.VARCHAR(20),
              'REG_TM': sql_types.TIMESTAMP,
              "UPD_TM": sql_types.TIMESTAMP,
              "LAST_LOGIN_DT": sql_types.TIMESTAMP,
              "CONFIRM_DT": sql_types.TIMESTAMP,
              "CANCEL_DT": sql_types.TIMESTAMP,
              "SECSN_DT": sql_types.TIMESTAMP,
              "INFO_AGREE_DT": sql_types.TIMESTAMP

          }
          )

tb_conn.close()

print("Total  : %s seconds" % (time.time() - start_time))
print("to_sql : %s seconds" % (time.time() - start_time1))



오류.참고.리눅스 파이썬 psycopg2 패키지 설치 오류 해결 )

파이썬 3.8버전 기준 리눅스에서 테스트

관련 의존성 라이브러리를 pip로 설치한다.

sudo pip3.8 install sqlalchemy

sudo pip3.8 install jaydebeapi

sudo pip3.8 install pandas

sudo pip3.8 install psycopg2

 

Error: pg_config executable not found. 

에러 발생시 postgresql과 설정에 문제가 있어서 발생 

sudo yum install postgresql postgresql-devel python3-devel

설치 후

다시 설치

sudo pip3.8 install psycopg2

gcc 관려 에러가 발생하면 gcc도 설치 해 준다.

 

sudo yum install gcc

 

/* 리눅스에서 대량의 데이타 sqlalchemy를 사용하여 처리하기 */

/* jdbc 폴더를 만든후에 jdbc드라이브 파일을 올린다 */

파이쎤 파일을 생성한다.

vi test.py

#!/usr/bin/python3.8

from sqlalchemy import create_engine
import sqlalchemy.types as sql_types
import jaydebeapi as jp
import pandas as pd
import time

tibero_JDBC_Driver = './jdbc/tibero6-jdbc.jar'
drivers = [tibero_JDBC_Driver]


def postgres_connect(user, password, db, host, port=5432):
    url = 'postgresql://{}:{}@{}:{}/{}'.format(user, password, host, port, db)
    engine = create_engine(url, client_encoding='utf8',
                           executemany_mode='batch')
    return engine


def tibero_connect():
    conn = jp.connect('com.tmax.tibero.jdbc.TbDriver',
                      'jdbc:tibero:thin:@192.168.1.19:9027:test', ['test', 'test'], jars=drivers)
    return conn



user = 'postgres'
password = 'postgres'
db = 'naqs'
host = '192.168.1.26'

query2 = """
    SELECT *
      FROM tibero.table
    """

start_time = time.time()
tb_conn = tibero_connect()
df = pd.read_sql_query(query2, tb_conn)

pg_engine = postgres_connect(user, password, db, host)
start_time1 = time.time()

print(df.columns)

df.to_sql('test_tmp',
          schema='public',
          con=pg_engine,
          if_exists='replace',  # {'fail', 'replace', 'append'), default 'fail'
          chunksize=1000,
          index=False,
          method='multi',
          dtype={
              'LGN_ID': sql_types.VARCHAR(20),
              'REG_TM': sql_types.TIMESTAMP,
              "UPD_TM": sql_types.TIMESTAMP,
              "LAST_LOGIN_DT": sql_types.TIMESTAMP,
              "CONFIRM_DT": sql_types.TIMESTAMP,
              "CANCEL_DT": sql_types.TIMESTAMP,
              "SECSN_DT": sql_types.TIMESTAMP,
              "INFO_AGREE_DT": sql_types.TIMESTAMP,
              "CD_LEN": sql_types.NUMERIC,
              "ARA_ORDER": sql_types.NUMERIC,
              "LATITUDE": sql_types.NUMERIC,
              "LONGITUDE": sql_types.NUMERIC,
              "REG_DTTM": sql_types.TIMESTAMP,
              "UPD_DTTM": sql_types.TIMESTAMP,
              "HLDY_DT": sql_types.TIMESTAMP

          }
          )

tb_conn.close()

print("Total  : %s seconds" % (time.time() - start_time))
print("to_sql : %s seconds" % (time.time() - start_time1))

저장후 테스트 실행한다.

실행 권한을 부여후 실행

[python@localhost python]$ chmod 755 test.py

 

[python@localhost python]$ ll
합계 4
drwxrwxr-x. 2 python python   78 12월 23 01:03 jdbc
-rwxr-xr-x. 1 python python 3113 12월 23 01:10 test.py

 

 

[python@localhost python]$ ./test.py
Index(['LAWD_CD', 'SD_NM', 'SD_SHORT_NM', 'SGG_NM', 'EMD_NM', 'RI_NM', 'SD_CD',
       'SGG_CD', 'EMD_CD', 'RI_CD', 'EFTV_YN', 'RMK', 'REGR_ID', 'REG_TM',
       'UPDR_ID', 'UPD_TM', 'DT', 'END_DT'],
      dtype='object')
Total  : 15.065675735473633 seconds
to_sql : 9.883891820907593 seconds

 

/* 대량의 데이타 처리 끝 */



출처: https://cbwstar.tistory.com/entry/파이썬-psycopg2-패키지-설치-오류-해결?category=1021765 [C.B.W 블로그]

 

반응형

'Database 관리 > Tibero' 카테고리의 다른 글

Spool 옵션  (0) 2022.01.11
Tibero 2 CSV  (0) 2022.01.07

linux.append syntax) shell 에서 파일 각 줄끝에 새로운 문자열 추가

Shell Script, Command, Batch, 쉘스크립트, 배치
반응형

# 참조 : https://cafe-de-java.tistory.com/7?category=757531

DB LINK를 이용해서 ITAS로 Oracle의 데이타를 Tibero로 이관 작업을 하는 중에

ITAS 다음에 바로 COMMIT을 주고 싶었는데, 

 

INSERT INTO TB0001 SELECT * FROM TB0001@ORA_DEV; COMMIT;

 

이런식으로 한 줄로 출력할 경우 문법 에러가 발생하게 된다.

 

그래서 짝수 번째 줄에 COMMIT; 문장을 출력해주는 스크립트를 꼼수로 작성해 보았다.

 

아래는 ITAS로 이루어진 itas_gen_sql.sql 파일

INSERT INTO USER1.TB0001 SELECT * FROM USER1.TB0001@ORA_DEV;

INSERT INTO USER1.TB0002 SELECT * FROM USER1.TB0002@ORA_DEV;

INSERT INTO USER1.TB0003 SELECT * FROM USER1.TB0003@ORA_DEV;

INSERT INTO USER1.TB0004 SELECT * FROM USER1.TB0004@ORA_DEV;

INSERT INTO USER1.TB0005 SELECT * FROM USER1.TB0005@ORA_DEV;

INSERT INTO USER1.TB0006 SELECT * FROM USER1.TB0006@ORA_DEV;

 

꼼수로 맨 마지막 글자가 세미콜론(;) 임을 이용해서 세미콜론뒤에 콜론을 하나더 붙여서, 콜론을 개행처리한 후 COMMIT; 을 추가하였다.

 

cat itas_gen_sql.sql | sed 's/\;/\;\:/g' | tr ':' '\n' | sed 's/^$/commit\;/g' > itas_gen_sql.sql_commit.sql

 

그럼 itas_gen_sql_commit.sql 파일은 아래와 같이 작성되어 있다.

 

INSERT INTO USER1.TB0001 SELECT * FROM USER1.TB0001@ORA_DEV;

COMMIT;

INSERT INTO USER1.TB0002 SELECT * FROM USER1.TB0002@ORA_DEV;

COMMIT;

INSERT INTO USER1.TB0003 SELECT * FROM USER1.TB0003@ORA_DEV;

COMMIT;

INSERT INTO USER1.TB0004 SELECT * FROM USER1.TB0004@ORA_DEV;

COMMIT;

INSERT INTO USER1.TB0005 SELECT * FROM USER1.TB0005@ORA_DEV;

COMMIT;

INSERT INTO USER1.TB0006 SELECT * FROM USER1.TB0006@ORA_DEV;

COMMIT;

 

TIP 으로 참고하길 바람

반응형

vlookup, index, match

사무, 엑셀, Excel
반응형

# 참조 : https://lightblog.tistory.com/108

 

다음과 같은 자료에서

 

 

조건1은 "2"고 조건2는 "c"인 값만 찾으려면 어떻게 해야 할까?

 

말하자면 VLOOKUP 에 두 가지 조건을 거는 것인데 가끔 생각이 안 날 때가 있다.

 

방법은 3가지로, 각각 VLOOKUP, INDEX-MATCH, 배열수식을 사용하는 방법이다.

 

 

1. 하나의 열을 추가하고 VLOOKUP 을 사용

 

VLOOKUP을 사용하려면 열을 하나 추가해야 한다.

 

다음과 같이 A와 B열의 문자열을 &로 묶는 열을 하나 만든다.

 

 

새로 만든 A열에서 VLOOKUP으로 "2c"를 찾는다.

 

 

같은 방법으로 3개, 4개의 조건도 동일하게 찾을 수 있다.

 

 

2. 열 추가 없이 INDEX-MATCH 사용

 

2018/06/13 - [엑셀] - [엑셀] 최초로 0이 아닌 값이 나오는 곳 찾기 INDEX() MATCH()에 등장한 방법을 이용하면

 

열 추가 없이도 1번과 같은 효과를 낼 수 있다.

 

일단 INDEX()를 활용해 A열과 B열을 &로 연결한 배열을 만들자.

 

=INDEX(A:A&B:B,)

 

 

"조건1조건2"라는 문자열이 반환되고 있다. 

 

1번에서 A열과 B열을 결합해 만든 별도의 열을, INDEX()를 활용해 가상으로 만들고 있다고 생각해도 되겠다.

 

이제 MATCH()를 이용해 그 배열에서 "2c" 인 곳의 위치를 찾는다.

 

=MATCH("2c", INDEX(A:A&B:B,), 0)

 

MATCH()의 마지막 인자로는 완전일치를 의미하는 0을 적어준다.

 

IF를 이용한 배열수식은 아니므로 Ctrl + Shift + Enter 를 누를 필요는 없다.

 

 

배열의 7번째 요소, 말하자면 7행이라고 값을 반환해주는 것을 알 수 있다.

 

이제 이것을 셀 주소인 C7 으로 바꿔야 하므로 다시 INDEX()를 활용해 "C열의 7번째" 임을 알려주자.

 

=INDEX(C:C, MATCH("2c", INDEX(A:A&B:B,), 0))

 

 

이와 같이 A열과 B열을 결합한 가상의 배열을 만들어 "2c"에 해당하는 값을 찾을 수 있다.

 

같은 방법으로 세 가지, 네 가지의 다중조건도 찾을 수 있다.

 

 

3. 원하는 값이 숫자라면 배열수식도 가능

 

최종적으로 반환되는 값이 숫자라면 2017/07/13 - [엑셀] - [엑셀] 배열수식에 여러 개의 조건 사용하기에서 본 대로 

 

배열수식을 이용하여 구할 수도 있다.

 

A열은 "2"고 B열은 "c"인 행들의 C열 값으로 만든 배열

 

을 다음과 같이 만들자.

 

=IF((A:A=2)*(B:B="c"),C:C)

 

이제 이 배열의 앞뒤로 SUM()이나 AVERAGE()등을 둘러싼 후 Ctrl + Shift + Enter를 누르면 완성이다. 

 

원하는 결과값이 하나라면 SUM()이나 AVERAGE() 모두 별도로 계산할 것이 없으므로 단순히 해당 값을 반환해 줄 것이다.

 

 

혹은 목적에따라 MAX()나 MIN()으로 둘러싸 주어도 되겠다.

 

 

(수식을 보는 함수 FORMULATEXT()는 2017/08/10 - [엑셀] - [엑셀] 수식 내용을 그대로 표시하는 세 가지 방법 참고)

 

 

 


 

 

혹시 구글 스프레드시트, 혹은 오피스 365를 사용할 수 있는 환경이라면

 

다음과 같이 Filter() 함수를 사용하는 것도 좋은 방법이다.

반응형

'사무, 엑셀, Excel' 카테고리의 다른 글

Power Automate.SQL.기본  (0) 2022.11.18
Shaping Arrays Function  (0) 2022.10.12
vba.여러 셋의 세로데이터를 가로 데이타로  (0) 2021.01.25
Web Data 긁어오기  (0) 2018.12.02
엑셀 단축키, 선택영역 채우기  (0) 2018.05.23