이 글에서는 cursor의 개념을 되짚어보고, 데이터베이스 내부의 cursor와 Python에서 사용하는 cursor 간의 공통점과 차이점을 살펴봅니다. 또한 쿼리 엔진에 접속하는 방식의 통신, 로깅 차이를 짧게 비교했습니다. 마지막으로 연결 자원을 효과적으로 사용하는 방법과 연결 관리를 위한 주요 기법을 정리합니다.
데이터베이스 Cursor 개념 비교
Python 프로젝트에서 데이터베이스 질의를 위해 사용하는 cursor
객체는 데이터베이스 내부에서의 cursor와 개념적으로 유사하지만, 동작 환경과 관리 주체에서 차이가 있습니다.
공통점
- 쿼리 실행 및 결과 순회: 두 cursor 모두 SQL 쿼리를 실행하고, 결과 집합을 순회하거나 조작하는 데 사용됩니다.
- 상태 관리: 쿼리 실행 결과를 추적하고, 결과의 위치나 상태를 관리합니다.
차이점
- 위치: 데이터베이스 내부 cursor는 DBMS 엔진 내에서 실행되며, Python의 cursor는 데이터베이스 연결을 추상화한 클라이언트 측 객체입니다.
- 관리 주체: 데이터베이스 cursor는 DBMS가 관리하는 반면, Python cursor는 애플리케이션 코드에서 직접 생성 및 해제해야 합니다.
즉 코드에서 정의하는 cursor는 실제 데이터베이스에서의 cursor를 언어 레벨에서 추상화한 형태입니다.
Python에서 Cursor 사용하기
Cursor를 활용한 예시 (impyla)
Python에서 impala 서버 접속시 cursor를 생성은 다음과 같이 사용됩니다:
from impala.dbapi import connect
# Impala에 연결 생성
conn = connect(host='impala_host', port=21050, auth_mechanism="GSSAPI", kerberos_service_name="impala")
# Cursor 객체 생성
cursor = conn.cursor()
# SQL 쿼리 실행
cursor.execute("SELECT * FROM users")
# 결과 순회
for row in cursor.fetchall():
print(row)
# Cursor와 연결 해제
cursor.close()
conn.close()
위 코드에서는 데이터베이스에 연결하고 cursor를 통해 SQL 쿼리를 실행한 후, 결과를 가져오고 연결을 해제합니다.
커맨드라인 쿼리 실행 방식과 Cursor 사용 방식 비교
impala-shell을 통해 쿼리 엔진에 접속하여도 동일한 처리를 수행할 수 있지만 cursor를 사용하면 커넥션과 cursor 객체를 통해 결과를 가져오고 프로그래밍적으로 처리할 수 있습니다. 프로젝트 코드에서 메서드로 관리하고 쿼리 실행결과를 받아서 처리하는 방식이 더 편하게 지원됩니다. 하지만 커맨드라인으로 수행하는 방식보다 쿼리 수행에 대한 로깅은 사용하는 라이브러리에 제약이 있을 수 있습니다.
통신 방식 | 로깅 | |
Impala-shell | Impala 서버와 직접 통신하는 CLI 클라이언트 | Impala 서버의 로그 수준과 설정을 기반으로 동작하며, 서버에서 발생하는 쿼리 요청과 응답의 세부 정보를 표준 출력 및 로그 파일에 기록합니다.
|
Cursor(impala.dbapi.connect) | 서버와의 통신을 위해 Thrift 프로토콜을 사용 | impala.dbapi는 표준 출력으로 로그를 남기는 기능을 기본 제공하지 않습니다. 사용자가 명시적으로 로깅 설정을 추가해야만 합니다.
|
연결 관리 방법
데이터베이스 연결 관리는 애플리케이션의 안정성과 성능을 유지하는 데 필수적입니다. 연결을 제대로 관리하지 않으면 다음과 같은 문제가 발생할 수 있습니다:
- 연결 누수: 닫히지 않은 연결이 점점 쌓여 데이터베이스의 동시 연결 한도를 초과할 수 있습니다.
- 자원 낭비: 사용하지 않는 연결이 메모리와 CPU를 소모합니다.
- 성능 저하: 데이터베이스와 애플리케이션의 응답 속도가 느려질 수 있습니다.
1. 메서드로 명시적 해제
cursor
와 connection
객체는 사용이 끝난 후 명시적으로 close()
메서드를 호출해 자원을 해제해야 합니다.
cursor.close()
conn.close()
2. with문을 활용한 자동 관리
Python의 with
문을 사용하면 자원 관리를 자동으로 처리할 수 있습니다. 이는 명시적으로 해제를 호출하지 않아도 연결이 자동으로 닫히므로, 코드의 안전성과 가독성을 높입니다.
with connect(host='impala_host', port=21050) as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
rows = cursor.fetchall()
print(rows)
# with 블록 종료 시 conn과 cursor가 자동으로 닫힘
3. Connection Pool 활용
데이터베이스 연결을 효율적으로 관리하려면 Connection Pool을 사용하는 것이 좋습니다. Connection Pool은 연결을 재사용하여 새로운 연결 생성 비용을 줄이고, 연결 누수를 방지합니다.
ImpalaConnectionPool
Kerberos RealmKrbRealmThe realm of the Impala host. If your Kerberos configuration already defines the realm of the Impala host as the default realm, then you do not need to configure this property.Supports Expression Language: true (will be evaluated usin
docs.cloudera.com
직접 구현한 connection pool을 사용하는 방식
rom impala.dbapi import connect
from queue import Queue
# Connection Pool 생성
class ConnectionPool:
def __init__(self, size):
self.pool = Queue(maxsize=size)
for _ in range(size):
conn = connect(host='impala_host', port=21050)
self.pool.put(conn)
def get_connection(self):
return self.pool.get()
def return_connection(self, conn):
self.pool.put(conn)
# Connection Pool 사용
pool = ConnectionPool(size=5)
conn = pool.get_connection()
try:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users")
print(cursor.fetchall())
finally:
pool.return_connection(conn)
결론
Python에서의 cursor는 데이터베이스 내부 cursor와 개념적으로 유사하며, SQL 쿼리 실행과 결과 관리의 핵심 역할을 합니다. 그러나 관리 주체와 사용 방식에서 차이가 있으므로, Python 프로젝트에서는 cursor와 연결 객체를 명시적으로 닫거나 with
문, Connection Pool을 활용하여 자원을 효율적으로 관리하는 것이 중요합니다. 이를 통해 데이터베이스 성능과 코드 안정성을 모두 확보할 수 있습니다.
참고자료
'CS > 데이터베이스' 카테고리의 다른 글
정규화 (0) | 2022.11.20 |
---|---|
데이터베이스 이상현상 (0) | 2022.11.20 |
데이터베이스 개념, 데이터 무결성 (0) | 2022.11.20 |