Oracle DB 연결 방법을 알아보겠습니다.
1) Python 패키지 설치
sqlalchemy, cx_Oracle 라이브러리 두개를 설치해야합니다.
pip install sqlalchemy
pip install cx_Oracle
2) Instant Client 설치
cx_Oracle을 사용하려면 Oracle Instant Client가 필요합니다. Windows 환경에서 설치하는 방법은 다음과 같습니다.
2.1. Instant Client 다운로드
- Oracle 공식 사이트에서 Windows용 Instant Client를 다운로드합니다.
- Instant Client Basic Package (ZIP 파일) 을 다운로드합니다.
- 다운로드한 ZIP 파일을 적절한 폴더(C:\oracle\instantclient_23_7 등)에 압축 해제합니다. (파일명은 선택한 버전에 따라 달라질 수 있습니다.)
2.2. 환경 변수 설정
- 시스템 환경 변수 추가
- INSTANT_CLIENT 환경 변수를 추가하고 Instant Client 경로를 입력합니다.
- 예: C:\oracle\instantclient_23_7
- Path 변수에 추가
- C:\oracle\instantclient_23_7 을 Path 환경 변수에 추가합니다.
3) Oracle DB Sample Table 추가
2.1편에서 생성한 Oracle 에 다음 sql 을 사용하여 Sample Table 을 추가하였습니다.
-- EMP 테이블 생성
CREATE TABLE EMP (
EMPNO NUMBER(4) PRIMARY KEY,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2)
);
-- DEPT 테이블 생성
CREATE TABLE DEPT (
DEPTNO NUMBER(2) PRIMARY KEY,
DNAME VARCHAR2(14),
LOC VARCHAR2(13)
);
-- BONUS 테이블 생성
CREATE TABLE BONUS (
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
SAL NUMBER,
COMM NUMBER
);
-- SALGRADE 테이블 생성
CREATE TABLE SALGRADE (
GRADE NUMBER,
LOSAL NUMBER,
HISAL NUMBER
);
-- DUMMY 테이블 생성
CREATE TABLE DUMMY (
DUMMY CHAR(1)
);
-- 데이터 삽입
INSERT INTO DEPT VALUES (10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT VALUES (20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT VALUES (30, 'SALES', 'CHICAGO');
INSERT INTO DEPT VALUES (40, 'OPERATIONS', 'BOSTON');
INSERT INTO EMP VALUES (7369, 'SMITH', 'CLERK', 7902, TO_DATE('1980-12-17', 'YYYY-MM-DD'), 800, NULL, 20);
INSERT INTO EMP VALUES (7499, 'ALLEN', 'SALESMAN', 7698, TO_DATE('1981-02-20', 'YYYY-MM-DD'), 1600, 300, 30);
INSERT INTO EMP VALUES (7521, 'WARD', 'SALESMAN', 7698, TO_DATE('1981-02-22', 'YYYY-MM-DD'), 1250, 500, 30);
INSERT INTO EMP VALUES (7566, 'JONES', 'MANAGER', 7839, TO_DATE('1981-04-02', 'YYYY-MM-DD'), 2975, NULL, 20);
INSERT INTO EMP VALUES (7698, 'BLAKE', 'MANAGER', 7839, TO_DATE('1981-05-01', 'YYYY-MM-DD'), 2850, NULL, 30);
INSERT INTO EMP VALUES (7782, 'CLARK', 'MANAGER', 7839, TO_DATE('1981-06-09', 'YYYY-MM-DD'), 2450, NULL, 10);
INSERT INTO EMP VALUES (7788, 'SCOTT', 'ANALYST', 7566, TO_DATE('1987-07-13', 'YYYY-MM-DD'), 3000, NULL, 20);
INSERT INTO EMP VALUES (7839, 'KING', 'PRESIDENT', NULL, TO_DATE('1981-11-17', 'YYYY-MM-DD'), 5000, NULL, 10);
INSERT INTO EMP VALUES (7902, 'FORD', 'ANALYST', 7566, TO_DATE('1981-12-05', 'YYYY-MM-DD'), 3000, NULL, 20);
INSERT INTO EMP VALUES (7934, 'MILLER', 'CLERK', 7782, TO_DATE('1982-01-23', 'YYYY-MM-DD'), 1300, NULL, 10);
INSERT INTO SALGRADE VALUES (1, 700, 1200);
INSERT INTO SALGRADE VALUES (2, 1201, 1400);
INSERT INTO SALGRADE VALUES (3, 1401, 2000);
INSERT INTO SALGRADE VALUES (4, 2001, 3000);
INSERT INTO SALGRADE VALUES (5, 3001, 9999);
INSERT INTO DUMMY VALUES ('X');
COMMIT;
4) Python에서 cx_Oracle 사용하기
import cx_Oracle
# Oracle Instant Client가 올바르게 설정되었는지 확인
print(cx_Oracle.clientversion())
# Oracle 데이터베이스 연결
dsn = cx_Oracle.makedsn("your_host", 1521, service_name="your_service_name")
connection = cx_Oracle.connect(user="your_username", password="your_password", dsn=dsn)
# 커서 생성
cursor = connection.cursor()
# 데이터 조회 예제
cursor.execute("SELECT * FROM your_table")
for row in cursor.fetchall():
print(row)
# 리소스 해제
cursor.close()
connection.close()
2.1편에서 생성한 Oracle 설정에 맞추어 다음과 같이 수정하였습니다.
connect_oracle_table.py
import cx_Oracle
# Oracle Instant Client가 올바르게 설정되었는지 확인
print(cx_Oracle.clientversion())
# Oracle 데이터베이스 연결
dsn = cx_Oracle.makedsn("192.168.56.10", 1521, service_name="XEPDB1")
connection = cx_Oracle.connect(user="testuser", password="test1234", dsn=dsn)
# 커서 생성
cursor = connection.cursor()
# 데이터 조회 예제
cursor.execute("SELECT * FROM EMP")
for row in cursor.fetchall():
print(row)
# 리소스 해제
cursor.close()
connection.close()
실행 결과는 다음과 같습니다.
EMP 테이블의 데이터가 정상적으로 검색됨을 확인 할 수 있습니다.
insert_sample.sql
(23, 7, 0, 25, 1)
(7369, 'SMITH', 'CLERK', 7902, datetime.datetime(1980, 12, 17, 0, 0), 800.0, None, 20)
(7499, 'ALLEN', 'SALESMAN', 7698, datetime.datetime(1981, 2, 20, 0, 0), 1600.0, 300.0, 30)
(7521, 'WARD', 'SALESMAN', 7698, datetime.datetime(1981, 2, 22, 0, 0), 1250.0, 500.0, 30)
(7566, 'JONES', 'MANAGER', 7839, datetime.datetime(1981, 4, 2, 0, 0), 2975.0, None, 20)
(7698, 'BLAKE', 'MANAGER', 7839, datetime.datetime(1981, 5, 1, 0, 0), 2850.0, None, 30)
(7782, 'CLARK', 'MANAGER', 7839, datetime.datetime(1981, 6, 9, 0, 0), 2450.0, None, 10)
(7788, 'SCOTT', 'ANALYST', 7566, datetime.datetime(1987, 7, 13, 0, 0), 3000.0, None, 20)
(7839, 'KING', 'PRESIDENT', None, datetime.datetime(1981, 11, 17, 0, 0), 5000.0, None, 10)
(7902, 'FORD', 'ANALYST', 7566, datetime.datetime(1981, 12, 5, 0, 0), 3000.0, None, 20)
(7934, 'MILLER', 'CLERK', 7782, datetime.datetime(1982, 1, 23, 0, 0), 1300.0, None, 10)
5) Oracle 검색 후 결과를 Qt 에 출력
이번에는 좀더 복잡한 Pyqt5 에 이름을 검색하여 결과를 출력하는 예제를 만들어보겠습니다.
ChatGPT에 사용한 프롬프트입니다.
pyqt5 로 실행 시 window 에 다음을 추가해주세요.
첫째 라인 : EMP Name 라는 GroupBox 로 둘러싸인 LineEdit, Search 버튼
둘째 라인 : Name, Job 이라는 Column 을 가지는 Grid
Oracle 정보는 다음과 같습니다.
host : 192.168.56.10
service name : XEPDB1
user : testuser
password : test1234
EMP Table 은 다음과 같습니다.
CREATE TABLE EMP (
EMPNO NUMBER(4) PRIMARY KEY,
ENAME VARCHAR2(10),
JOB VARCHAR2(9),
MGR NUMBER(4),
HIREDATE DATE,
SAL NUMBER(7,2),
COMM NUMBER(7,2),
DEPTNO NUMBER(2)
);
Seach 버튼을 클릭하면 cx_Oracle 로 EMP 테이블을 검색하여 EMP Name LineEdit 에 입력된 값으로 검색하여 Name 이 일치하는
레코드를 찾습니다.
일치하는 데이터를 찾으면 Grid 에 Name, Job 를 추가합니다.
생성된 코드입니다.
아래 코드는 다음 git 에서도 다운받을 수 있습니다.
git clone git@github.com:jbpark/jbDeskExample.git
cd jbDeskExample/jbDesk/ch2.2
search_oracle_table.py
import sys
import cx_Oracle
from PyQt5.QtWidgets import (
QApplication, QWidget, QVBoxLayout, QGroupBox, QLineEdit, QPushButton,
QTableWidget, QTableWidgetItem, QHBoxLayout
)
class EmployeeSearchApp(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
layout = QVBoxLayout()
# EMP Name GroupBox
self.groupBox = QGroupBox("EMP Name")
groupBoxLayout = QHBoxLayout()
self.searchInput = QLineEdit()
self.searchButton = QPushButton("Search")
self.searchButton.clicked.connect(self.searchEmployee)
groupBoxLayout.addWidget(self.searchInput)
groupBoxLayout.addWidget(self.searchButton)
self.groupBox.setLayout(groupBoxLayout)
# 결과 테이블
self.resultTable = QTableWidget()
self.resultTable.setColumnCount(2)
self.resultTable.setHorizontalHeaderLabels(["Name", "Job"])
layout.addWidget(self.groupBox)
layout.addWidget(self.resultTable)
self.setLayout(layout)
self.setWindowTitle("Employee Search")
self.resize(400, 300)
def searchEmployee(self):
emp_name = self.searchInput.text().strip()
if not emp_name:
return
# Oracle DB 연결 정보
dsn = cx_Oracle.makedsn("192.168.56.10", 1521, service_name="XEPDB1")
conn = cx_Oracle.connect(user="testuser", password="test1234", dsn=dsn)
cursor = conn.cursor()
# EMP 테이블 검색
query = """
SELECT ENAME, JOB FROM EMP WHERE ENAME = :ename
"""
cursor.execute(query, ename=emp_name)
results = cursor.fetchall()
# 테이블에 데이터 채우기
self.resultTable.setRowCount(len(results))
for row_idx, row_data in enumerate(results):
self.resultTable.setItem(row_idx, 0, QTableWidgetItem(row_data[0]))
self.resultTable.setItem(row_idx, 1, QTableWidgetItem(row_data[1]))
cursor.close()
conn.close()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = EmployeeSearchApp()
window.show()
sys.exit(app.exec_())
실행 결과는 다음과 같습니다.
쉽지 않나요?
ChatGPT 에 연동에 필요한 정보만 정확하게 알려주면 바로 바로 실행할 수 있는 코드를 알려주네요.
세상 참 좋아졌어요.
ChatGPT 등의 인공지능을 사용하여 코딩하는 세대를 AI Native 세대라고 하더라구요.
정말 인공지능은 선택이 아닌 필수인 것 같습니다.
6) JbDesk 와 통합
JbDesk 에 Oracle 연동 메뉴도 통합하였습니다.
관련 코드는 다음 git 에서 다운받을 수 있습니다.
git clone git@github.com:jbpark/jbDeskExample.git
cd jbDeskExample/jbDesk/ch2.2
JbDesk.py
'유틸리티 > JbDesk' 카테고리의 다른 글
JbDesk 3.1편-Python fabric 으로 원격 커맨드 실행 (0) | 2025.04.08 |
---|---|
JbDesk 2.3편-Database 검색 (MariaDb + Multi-tenant) (1) | 2025.04.05 |
JbDesk 2.1편-Database 검색 (SQLite + SQLAlchemy) (0) | 2025.03.28 |
JbDesk 1.6편-코드 리팩터링 (1) | 2025.03.28 |
JbDesk 1.5편-exe 만들기 (0) | 2025.03.28 |