설치
Anaconda Prompt
conda install -c anaconda cx_oracle
(base) C:\Users\ITWILL>lsnrctl status : 상태정보
import pandas as pd
from pandas import Series, DataFrame
emp = pd.read_csv('c:/data/emp.csv')
dept = pd.read_csv('c:/data/dept.csv')
■ 파이썬에서 오라클 접속
import cx_Oracle
오라클 접속
# 계정명, 비번, HOST명:PORT번호/serviece이름, encoding
conn = cx_Oracle.connect("hr","hr","DESKTOP-E88DR0D:1521/xe",encoding="UTF-8")
cursor = conn.cursor()
cursor.execute("select * from employees")
data = cursor.fetchall()
data
# 컬럼 정보는 숫자로 표현
df = DataFrame(data)
df
# 컬럼 확인
select column_name
from user_tab_columns
where table_name = 'EMPLOYEES';
cursor.execute (""" select column_name
from user_tab_columns
where table_name = 'EMPLOYEES'
""")
col = cursor.fetchall()
col
# 튜플타입을 list 타입으로 변형
# for문 + for문
[j for i in col for j in i ]
col_new = [j for i in col for j in i ]
col_new
# 컬럼명 수정
df.columns = col_new
df
# 테이블 생성
cursor.execute("""create table insa(id number, name varchar2(30), day date)""")
cursor.execute("""insert into insa(id, name, day) values(1, '홍길동', sysdate)""")
cursor.execute("""select * from insa""")
cursor.fetchall()
cursor.execute("commit") # select * from insa;
# rollback
cursor.execute("""insert into insa(id, name, day) values(2, '박찬호', sysdate)""")
cursor.execute("""select * from insa""")
cursor.fetchall()
cursor.execute("rollback")
cursor.execute("""select * from insa""")
cursor.fetchall()
# 변수로 data 로드하기
v_id = 2
v_name = '박찬호'
v_day = pd.Timestamp.now().date() # sysdate 는 sql 함수여서 사용X
cursor.execute("""insert into insa(id, name, day)
values(:b_id, :b_name, :b_day)""", # 바인드변수명으로 위치표현 지정
(v_id, v_name, v_day))
cursor.execute("commit")
cursor.execute("""select * from insa""")
cursor.fetchall()
# sql 쿼리문으로 별로의 변수로 지정
sql = """insert into insa(id, name, day) values(:b_id, :b_name, :b_day)"""
cursor.execute(sql,[3, '손흥민', pd.Timestamp.now()]) # 변수로 작성해도 무방
cursor.execute("commit")
cursor.execute("""select * from insa""")
cursor.fetchall()
# 바인드변수에 값을 지정
cursor.execute(sql, b_id=4, b_name='나얼', b_day=pd.Timestamp.now())
cursor.execute("commit")
cursor.execute("""select * from insa""")
cursor.fetchall()
# dict 형태로 값을 지정
data = dict(b_id=5, b_name='윤건', b_day=pd.Timestamp.now())
data
cursor.execute(sql,data)
cursor.execute("commit")
cursor.execute("""select * from insa""")
cursor.fetchall()
# 문제점) select 문 실행 → 동일한 실행계획을 생성
cursor.execute("""select * from insa where id = 1""")
cursor.fetchone()
cursor.execute("""select * from insa where id = 2""")
cursor.fetchone()
cursor.execute("""select * from insa where id = 3""")
cursor.fetchone()
Q) SQL문에 변수 처리하는 이유?
#- 실행계획을 공유하기 위한 목적(CPU, 메모리 사용을 줄일 수 있다.)
# 바인드변수 처리
cursor.execute("""select * from insa where id = :b_id""", 1) # 오류발생
cursor.fetchone()
cursor.execute("""select * from insa where id = :b_id""", [1]) # list 형식
cursor.fetchone()
cursor.execute("""select * from insa where id = :b_id""", (1,)) # 튜플형식
cursor.fetchone()
# 변수명
v_id = 1
cursor.execute("""select * from insa where id = :b_id""", [v_id])
cursor.fetchone()
cursor.execute("""select * from insa where id = :b_id""", (v_id,))
cursor.fetchone()
cursor.execute("""select * from insa where id = :b_id""", b_id = v_id)
cursor.fetchone()
# update 문
cursor.execute("""update insa set name = '제임스' where id = 2""")
cursor.execute("""select * from insa""")
cursor.fetchall()
cursor.execute("rollback")
# 변수 처리
v_id = 2
v_name = '제임스'
cursor.execute("""update insa set name = :b_name where id = :b_id""", b_name=v_name, b_id= v_id)
cursor.execute("""select * from insa""")
cursor.fetchall()
cursor.execute("rollback")
# delete 문
v_id = 2
cursor.execute("""delete from insa where id = :b_id""", b_id= v_id)
cursor.execute("""select * from insa""")
cursor.fetchall()
cursor.execute("rollback")
<<pandas datafram 을 오라클로 이관작업>>
from sqlalchemy.engine import create_engine
db_sw = 'oracle'
sql_driver = 'cx_oracle'
# 실무적으로 변경작업되는 부분
username = 'hr'
password = 'hr'
host = 'DESKTOP-E88DR0D'
port = 1521
service = 'xe'
# 오라클 연결 하는 작업을 변수처리해서 연결
(직접 코드 작성해도 가능하다!)
path = db_sw+'+'+sql_driver+'://'+username+':'+password+'@'+host+':'+str(port)+'/?service_name='+service
# oracle+cx_oracle://hr:hr@DESKTOP-E88DR0D:1521/?service_name=xe
path
engine = create_engine(path)
emp.to_sql('emp_new', engine, schema='hr', index=False) # 이관작업
emp.info()
<< 오라클에서 clob column 변경작업 >>
alter table emp_new modify commission_pct number;
alter table emp_new modify manager_id number;
alter table emp_new modify department_id number;
desc emp_new
select * from emp_new;
# FIRST_NAME CLOB : 타입이 변경이 되지 않음, 오류발생
alter table emp_new modify first_name varchar2(30);
# clob 을 varchar2(4000), char(2000) 수정할 수 없다.
# 기존 용량보다 초과되어 있다면, 조각해서 출력
select dbms_lob.substr(first_name, 4000, 1), dbms_lob.substr(first_name, 4000, 4001)
from emp_new;
#1. 새로운 컬럼을 생성
alter table emp_new add new_column varchar2(30);
desc emp_new
#2. clob의 컬럼을 varchar2 컬럼으로 수정 작업
update emp_new
set new_column = dbms_lob.substr(first_name, 4000, 1);
commit;
select * from emp_new;
#3. clob 컬럼 삭제
alter table emp_new drop column first_name;
desc emp_new
select * from emp_new;
#4. 새로운 컬럼이름을 기존 컬럼 이름 수정
alter table emp_new rename column new_column to first_name;
desc emp_new
■ 정규표현식(Regular Expression)
# 특정패턴과 일치하는 문자열 검색, 치환, 제거하는 기능을 제공한다.
■ 메타문자(meta characters)
# [A-Za-z]: [] 메타문자를 표현, - 범위를 표현
# 원래 문자가 가진 뜻이 아닌 특별한 용도로 사용하는 문자
[A-Za-z] | []사이의 문자들과 매치 |
[0-9] | 숫자 패턴 |
[sql] | s 또는 q 또는 l |
[가-힣ㄱ-ㅎㅏ-ㅣ] | 한글, 자모음 |
# 가장 많이 사용되는 메타문자
a.b | . 위치에 모든 문자를 의미(줄바꿈은 제외) |
a\.b | .을 문자로 인식 |
a[.]b |
a*b | * 바로 앞의 문자가 0 번 이상을 찾는다. | b, ab, aaab |
a+b | + 바로 앞의 문자가 1 번 이상을 찾는다. | ab, aab, aaab |
ab?c | ? 바로 앞의 문자가 0 번, 1번을 찾는다. | ac, abc |
a{2}b | {n} 바로 앞의 문자가 n 번 반복을 찾는다. | aab |
a{2, 3}b | {n, m} 바로 앞의 문자가 n 번 또는 m번 반복을 찾는다. | aab, aaab |
a{2,}b | {n,} 바로 앞의 문자가 n 번 이상을 찾는다. | aab, aaab, aaaab |
a|b | a 또는 b |
[^a] | [^] not 을 제외 (a 제외) |
^ | 시작 |
$ | 종료 |
\d | [0-9] 숫자 패턴을 찾을 때 |
\D | [^0-9] 숫자가 아닌 패턴을 찾을 때 |
\s | [ \t\n\r\f\v] 공백문자 |
\S | [^ \t\n\r\f\v] 공백문자가 아닌 패턴 |
\w | [a-zA-Z가-힣0-9] 문자 또는 숫자 패턴을 찾을 때 |
\W | [^a-zA-Z가-힣0-9] 문자, 숫자가 아닌 패턴을 찾을 때 |
import re
# re.match : 문자열의 처음부터 정규식과 매치되는지 찾는 함수
re.match('\w','a')
bool(re.match('\w','a'))
re.match('\w','100')
bool(re.match('\w','100'))
re.match('\w','_')
bool(re.match('\w','_'))
re.match('\w','python')
bool(re.match('\w','python'))
re.match('\w','-python')
bool(re.match('\w','-python'))
re.match('\W','-python')
bool(re.match('\W','-python'))
bool(re.match('[-]','-python'))
bool(re.match('[-]','py-thon'))
re.match('c*a','cat')
bool(re.match('c*a','cat'))
re.match('c*a','ccat')
bool(re.match('c*a','ccat'))
re.match('c+a','cat')
bool(re.match('c+a','cat'))
re.match('c+a','ccat')
bool(re.match('c+a','ccat'))
bool(re.match('c+a','at'))
re.match('c?a','cat')
bool(re.match('c?a','cat'))
re.match('c?a','at')
bool(re.match('c?a','at'))
re.match('c{2}a','cat')
bool(re.match('c{2}a','cat'))
re.match('c{2}a','ccat')
bool(re.match('c{2}a','ccat'))
re.match('c{2,3}a','ccccat')
bool(re.match('c{2,3}a','cccccat'))
re.match('c|a','at')
bool(re.match('c|a','at'))
bool(re.match('c|a','ct'))
bool(re.match('c|a','bat'))
bool(re.match('[0-9]th','21th'))
bool(re.match('[0-9][0-9]th','21th'))
bool(re.match('[0-9]{2}th','21th'))
bool(re.match('[0-9]*th','21th'))
bool(re.match('[0-9]+th','21th'))
bool(re.match('[0-9]?th','21th'))
bool(re.match('\d\dth','21th'))
bool(re.match('\d{2}th','21th'))
# 대소문자 구분
re.match('Or','Oracle engineer')
re.match('or','Oracle engineer')
#re.I 대소문자 구분
re.match('or','Oracle engineer',re.I)
m = re.match('Oracle','Oracle engineer')
m.group() # 매치된 문자열 리턴
m.span() # 매치된 문자열의 (시작, 끝)
m.start() # 매치된 문자열 시작위치
m.end() # 매치된 문자열 끝
'Oracle engineer'[m.start():m.end()]
# re.search() : 해당하는 문자열에서 어디서든지 찾는다.
re.match('engineer','Oracle engineer')
re.search('engineer','Oracle engineer')
m = re.search('engineer','Oracle engineer')
m.group()
m.span()
m.start()
m.end()
# re.findall() : 일치하는 문자열 전부를 리스트로 반환한다.
re.search('engineer','Oracle engineer Oracle engineer')
re.findall('engineer','Oracle engineer Oracle engineer')
# re.sub() : 패턴을 치환하는 함수
source = 'oracle engin'
source.replace('engin', 'engineer')
re.sub('engin', 'engineer', source)
# re.split() : 패턴을 이용해서 문자열 분리
'python.programming'.split('.')
re.split('\.', 'python.programming')
re.split('[.]', 'python.programming')
re.split('[.:]', 'python.programming:PLSQL')
re.split('[.: ]', 'python.programming:PLSQL SQL')
re.split('[.:\s]', 'python.programming:PLSQL SQL')